84 #ifdef DABC_EXTRA_CHECKS
86 Mutex gObjectGarbageMutex;
119 fObjectParent(parent),
134 fObjectParent(pair.parent),
135 fObjectName(pair.name),
151 DOUT5(
"Object destroyed %s %p", GetName(),
this);
157 SetFlag(flIsOwner, on);
163 SetFlag(flAutoDestroy, on);
170 return GetFlag(flIsOwner);
176 return GetFlag(flLogging);
182 return GetFlag(flChildsHidden);
188 return GetFlag(flTopXmlLevel);
194 return GetFlag(flHidden);
200 return SetFlag(flLogging, on);
205 if ((len==0) || (str==0))
return false;
206 if (len<0)
return fObjectName.compare(str) == 0;
207 return ((
int) fObjectName.length()==len) && (fObjectName.compare(0, len, str,len) == 0);
217 if (!GetFlag(flNoMutex))
218 fObjectMutex =
new Mutex(
false);
222 fObjectParent.AddChild(
this);
227 #ifdef DABC_EXTRA_CHECKS
230 gObjectGarbageCollector.remove(
this);
235 bool delchilds =
false;
240 if ((GetState() != stDestructor) && (fObjectRefCnt!=0)) {
241 EOUT(
"Object %p %s deleted not via Destroy method refcounter %u",
this, GetName(), fObjectRefCnt);
244 SetState(stDestructor);
246 if (fObjectRefCnt!=0) {
247 EOUT(
"!!!!!!!!!!!! Destructor called when refcounter %u obj:%s %p", fObjectRefCnt, GetName(),
this);
252 if (fObjectChilds!=0) {
254 if (fObjectChilds->GetSize() > 0)
255 EOUT(
"!!!!!!! CHILDS %u ARE NOT DELETED completely obj:%s %p", fObjectChilds->GetSize(), GetName(),
this);
257 if (fObjectBlock > 0)
258 EOUT(
"!!!! CHILDS ARE STILL BLOCKED %d!!!!!!!", fObjectBlock);
267 if (delchilds) RemoveChilds();
270 fObjectParent.Release();
282 if (GetState() == stDestructor) {
283 EOUT(
"OBJ:%p %s Inc reference during destructor",
this, GetName());
291 if (GetFlag(flLogging))
292 DOUT0(
"Obj:%s %p Class:%s IncReference +----- %u thrd:%s", GetName(),
this, ClassName(), fObjectRefCnt,
dabc::mgr.CurrentThread().GetName());
300 SetFlag(flCleanup,
true);
305 return GetState() == stNormal;
313 return _IsNormalState();
322 bool viathrd =
false;
339 if (fObjectRefCnt==0) {
340 EOUT(
"Obj %p name:%s class:%s Reference counter is already 0",
this, GetName(), ClassName());
348 if (GetFlag(flLogging))
349 DOUT0(
"Obj:%s %p Class:%s DecReference ----+- %u thrd:%s", GetName(),
this, ClassName(), fObjectRefCnt,
dabc::mgr.CurrentThread().GetName());
352 switch (GetState()) {
354 EOUT(
"Object %s is not yet constructed - most probably, big failure", GetName());
361 if (GetFlag(flAutoDestroy) && (fObjectRefCnt == 0)) ask_to_destroy =
true;
363 if (do_decrement && (fObjectChilds!=0) && ((
unsigned) fObjectRefCnt == fObjectChilds->GetSize()) && GetFlag(flAutoDestroy)) {
364 ask_to_destroy =
true;
368 if (!ask_to_destroy)
return false;
369 viathrd = GetFlag(flHasThread);
373 case stWaitForThread:
375 DOUT2(
"Object %p %s tried to destroy not from thread - IGNORE",
this, GetName());
385 case stWaitForDestructor:
386 if (fObjectRefCnt == 0) {
387 if (_DoDeleteItself())
return false;
391 SetState(stDestructor);
396 #ifdef DABC_EXTRA_CHECKS
399 if (!gObjectGarbageCollector.has_ptr(
this))
400 gObjectGarbageCollector.push_back(
this);
411 SetState(stWaitForThread);
414 if (GetFlag(flLogging))
415 DOUT0(
"Obj:%s %p Class:%s IncReference --+--- %u", GetName(),
this, ClassName(), fObjectRefCnt);
417 SetState(stDoingDestroy);
422 if (DestroyByOwnThread())
return false;
426 SetState(stDoingDestroy);
431 if (GetFlag(flLogging))
432 DOUT0(
"Obj:%s %p Class:%s DecReference -----+ %u", GetName(),
this, ClassName(), fObjectRefCnt);
436 if (IsLogging())
DOUT0(
"Calling object %p cleanup from_thrd=%s do_decrement=%s",
this,
DBOOL(from_thread),
DBOOL(do_decrement));
444 DOUT0(
"DecRefe after cleanup %p cleanup %s mgr %p",
this,
DBOOL(GetFlag(flCleanup)),
dabc::mgr());
453 SetState(stWaitForDestructor);
454 if (GetFlag(flLogging))
455 DOUT0(
"Obj:%s %p Class:%s IncReference ---+-- %u", GetName(),
this, ClassName(), fObjectRefCnt);
457 if (fObjectRefCnt==0) {
459 DOUT3(
"Obj:%p can be destroyed",
this);
460 if (_DoDeleteItself()) {
461 SetState(stWaitForDestructor);
464 SetState(stDestructor);
468 SetState(stWaitForDestructor);
469 #ifdef DABC_EXTRA_CHECKS
472 if (!gObjectGarbageCollector.has_ptr(
this))
473 gObjectGarbageCollector.push_back(
this);
483 if (
dabc::mgr()->DestroyObject(ref))
return false;
489 if (fObjectRefCnt==0) {
491 if (_DoDeleteItself()) {
492 SetState(stWaitForDestructor);
496 DOUT3(
"Obj:%p can be destroyed",
this);
497 SetState(stDestructor);
506 return DecReference(
true,
true,
true);
512 DOUT1(
"OBJ:%p %s DELETETHIS cnt %u",
this, GetName(), fObjectRefCnt);
517 if (GetState()!=stNormal) {
523 SetFlag(flCleanup,
true);
537 DOUT0(
"Obj:%p %s refcnt %u Before remove from parent %p",
this, GetName(), fObjectRefCnt, fObjectParent());
541 if (!fObjectParent.null())
542 fObjectParent()->RemoveChild(
this,
false);
544 if (!fObjectParent.null()) {
545 EOUT(
"Parent still not yet cleaned !!!!");
546 fObjectParent.Release();
550 DOUT0(
"Obj:%p %s refcnt %u after remove from parent",
this, GetName(), fObjectRefCnt);
553 DOUT3(
"Obj:%s Class:%s Finish cleanup numrefs %u", GetName(), ClassName(), NumReferences());
561 return fObjectRefCnt;
567 return AddChildAt(child, (
unsigned) -1, withmutex);
572 if (child==0)
return false;
575 EOUT(
"Cannot add child from other parent directly - first remove from old");
582 LockGuard guard(withmutex ? fObjectMutex : 0);
594 if (pos == (
unsigned) -1)
595 fObjectChilds->
Add(ref);
597 fObjectChilds->AddAt(ref, pos);
606 if (child==0)
return false;
608 if (child->fObjectParent() !=
this)
return false;
612 bool isowner =
false;
619 if (fObjectChilds==0)
return false;
621 if (fObjectBlock>0)
continue;
623 isowner = GetFlag(flIsOwner);
625 if (fObjectChilds->ExtractRef(child, childref)) {
632 if (child->fObjectParent.fObj==
this) {
633 child->fObjectParent.fObj = 0;
634 if (fObjectRefCnt>1) {
638 if (fObjectChilds->GetSize() > 0)
639 DOUT0(
"Object %p %s refcnt==0 when numchild %u",
this, GetName(), fObjectChilds->GetSize());
645 EOUT(
"Not able to extract child reference!!!");
649 if (cleanup && isowner) childref.
Destroy();
652 #ifdef DABC_EXTRA_CHECKS
654 DOUT0(
"Object %s Retry %d time before childs were unblocked", GetName(), 1000000-cnt);
658 EOUT(
"HARD error!!!! - For a long time fObjectBlock=%d is blocked in object %p %s", fObjectBlock,
this, GetName());
667 return RemoveChild(
GetChild(n), cleanup);
674 return fObjectChilds ? fObjectChilds->GetSize() : 0;
681 return fObjectChilds==0 ? 0 : fObjectChilds->GetObject(n);
688 Object* obj = (fObjectChilds==0) ? 0 : fObjectChilds->GetObject(n);
703 if (vect==0)
return false;
707 if (fObjectChilds==0)
return true;
711 for (
unsigned n=0; n<fObjectChilds->GetSize(); n++)
712 ptrs.push_back(fObjectChilds->GetObject(n));
718 for (
unsigned n=0;n<ptrs.size();n++) {
732 return FindChildRef(name,
false)();
739 return SearchForChild(ref, name,
true, force);
744 if (ref.null())
return ref;
746 if ((name==0) || (strlen(name)==0))
return ref;
752 return SearchForChild(ref, name+1,
false, force);
755 while (*name==
'/') name++;
756 if (*name==0)
return ref;
760 int len = strlen(name);
762 if ((len>=2) && (name[0]==
'.') && (name[1] ==
'.')) {
767 return SearchForChild(ref, name + 3,
false, force);
771 if ((len>=1) && (name[0]==
'.')) {
772 if (len==1)
return ref;
774 return SearchForChild(ref, name + 2,
false, force);
777 const char* ptok = name;
779 if (*ptok ==
'/')
break;
791 if ((obj==0) && force) {
797 IntGuard block(ref()->fObjectBlock);
808 if (*ptok==0)
return ref;
810 return SearchForChild(ref, ptok+1,
false, force);
818 return SearchForChild(ref, name.c_str(),
true, force);
827 bool isowner =
false;
833 if (fObjectChilds==0)
return true;
835 if (fObjectBlock>0)
continue;
837 isowner = GetFlag(flIsOwner);
838 del_vect = fObjectChilds;
843 #ifdef DABC_EXTRA_CHECKS
845 DOUT0(
"Object %s Retry %d times before childs were unblocked", 1000000-cnt);
849 EOUT(
"HARD error!!!! - For a long time fObjectBlock=%d is blocked in object %p %s", fObjectBlock,
this, GetName());
854 DOUT1(
"Obj:%s Deleting childs:%u", GetName(), del_vect ? del_vect->
GetSize() : 0);
859 for (
unsigned n=0;n<del_vect->
GetSize();n++) {
864 del_vect->
Clear(isowner && cleanup);
875 if (fObjectRefCnt>0) {
876 EOUT(
"Cannot change object name when reference counter %d is not zero!!!", fObjectRefCnt);
925 if (obj->DecReference(
true,
false))
936 if (fullnamearg.empty() && prnt.
null())
939 const char* fullname = fullnamearg.empty() ?
"---" : fullnamearg.c_str();
940 bool isrootfolder(
false), isskipparent(
false);
941 while (*fullname==
'/') {
946 if (!isrootfolder && (*fullname==
'#')) {
951 if (prnt.
null() && withmanager && !isskipparent) {
955 const char* slash = strrchr(fullname,
'/');
961 std::string path = std::string(fullname, slash - fullname);
963 prnt = prnt()->FindChildRef(path.c_str(),
true);
965 pair.
name = fullname;
987 if (obj==0)
return false;
992 if (prnt==obj)
return true;
1001 return NameMatch(fObjectName, mask);
1006 if ((mask.length()==0) || (name.length()==0))
1007 return name.length()==mask.length();
1009 size_t lastsepar(0), separ = mask.find_first_of(
';',lastsepar);
1011 if (separ!=std::string::npos) {
1017 }
while (lastsepar!=std::string::npos);
1021 if (mask.find_first_of(
"*?") == std::string::npos)
return name == mask;
1023 if (mask ==
"*")
return true;
1025 return fnmatch(mask.c_str(), name.c_str(), FNM_NOESCAPE)==0;
1030 size_t separ = mask.find_first_of(
':');
1032 if (separ==std::string::npos)
return NameMatch(name, mask);
1034 size_t lastsepar = 0;
1038 std::string submask;
1040 if (separ==std::string::npos)
1041 submask = mask.substr(lastsepar);
1043 if (separ>lastsepar)
1044 submask = mask.substr(lastsepar, separ-lastsepar);
1046 if (!submask.empty())
1047 if (NameMatch(name, submask))
return true;
1050 if (separ!=std::string::npos) {
1052 separ = mask.find_first_of(
':', lastsepar);
1055 }
while (lastsepar!=std::string::npos);
1064 GetParent()->FillFullName(fullname, upto, exclude_top_parent);
1065 fullname.append(
"/");
1069 if (exclude_top_parent)
return;
1070 fullname.append(
"/");
1072 fullname.append(GetName());
1080 dabc::mgr()->FillItemName(
this, res, compact);
1082 FillFullName(res, 0);
1101 #ifdef DABC_EXTRA_CHECKS
1104 DOUT0(
"GarbageCollector: there are %u objects in collector now", gObjectGarbageCollector.size());
1106 for (
unsigned n=0;n<gObjectGarbageCollector.size();n++) {
1117 #ifdef DABC_EXTRA_CHECKS
1123 void dabc::Object::DebugObject(
const char* classname,
Object* instance,
int kind)
1126 typedef std::list<dabc::Object*> obj_list;
1127 typedef std::map<std::string,obj_list> full_map;
1128 typedef std::map<std::string,int> counts_map;
1131 static counts_map cnts;
1132 static full_map objs;
1137 if (classname == 0) {
1138 printf(
"NUM ENTRIES = %u\n", (
unsigned) cnts.size());
1139 for (counts_map::iterator iter = cnts.begin(); iter != cnts.end(); iter++) {
1140 printf(
" CLASS = %s NUM = %d \n", iter->first.c_str(), iter->second);
1142 full_map::iterator iter2 = objs.find(iter->first);
1143 if (iter2!=objs.end())
1144 for (obj_list::iterator iter3 = iter2->second.begin(); iter3 != iter2->second.end(); iter3++)
1145 printf(
" OBJ:%p NAME = %s\n", *iter3, (*iter3)->GetName());
1148 std::string name(classname);
1149 if (kind<0) cnts[name]--;
1152 if (kind==10) objs[name].push_back(instance);
else
1153 if (kind==-10) objs[name].remove(instance);
Interface class between xml configuration and dabc objects.
bool FindItem(const char *name)
Lock guard for posix mutex.
static void Debug(int level, const char *filename, unsigned linenumber, const char *funcname, const char *message)
Base class for most of the DABC classes.
Reference fObjectParent
reference on the parent object
bool RemoveChild(Object *child, bool cleanup=true)
Detach child from parent object If cleanup==true and parent is owner of child, child will be destroye...
bool IsName(const char *str) const
Checks if object name is same as provided string, thread safe
void Destructor()
Destroys all internal data, reentrant.
bool IsOwner() const
Returns true if object is owner of its children, thread safe
bool IsTopXmlLevel() const
Return true if object should be searched in the top level of the xml file, thread safe
ReferencesVector * fObjectChilds
list of the child objects
virtual Object * CreateInstance(const std::string &name)
Method used to create new item to be placed as child of the object.
bool IncReference(bool withmutex=true)
Increments reference counter, return false if it cannot be done.
void FillFullName(std::string &fullname, Object *upto, bool exclude_top_parent=false) const
Method used to produce full item name,.
std::string ItemName(bool compact=true) const
Produce string, which can be used as name argument in dabc::mgr.FindItem(name) call.
Object * GetParent() const
Returns pointer on parent object, thread safe
bool DecReference(bool ask_to_destroy, bool do_decrement=true, bool from_thread=false)
Decrements reference counter, return true if object must be destroyed.
unsigned NumReferences()
Return number of references on the object.
virtual void Print(int lvl=0)
Print object content on debug output.
void Constructor()
Initializes all variables of the object.
bool RemoveChildAt(unsigned n, bool cleanup=true)
Detach child object from parent at specified position If cleanup==true and object is owner of child,...
Reference GetChildRef(unsigned n) const
returns reference on child object
static bool NameMatchM(const std::string &name, const std::string &mask)
Check if name matches to specified mask.
void SetNameDirect(const char *name)
Changes object name disregard of existing references.
static unsigned gNumCreated
number of created instances, will used for object id
Object(const ConstructorPair &pair, unsigned flags=flIsOwner)
void SetLogging(bool on=true)
Sets logging flag, thread safe
const char * GetName() const
Returns name of the object, thread safe
void SetAutoDestroy(bool on=true)
Set autodestroy flag for the object Once enabled, object will be destroyed when last reference will b...
static void InspectGarbageCollector()
\ brief Methods to inspect how many objects pointers are remained
int fObjectRefCnt
accounts how many references existing on the object, thread safe
static ConstructorPair MakePair(Reference prnt, const std::string &fullname, bool withmanager=true)
Internal DABC method, used to produce pair - object parent and object name, which is typically should...
virtual void ObjectCleanup()
User method to cleanup object content before it will be destroyed Main motivation is to release any r...
bool DestroyCalledFromOwnThread()
Internal DABC method, should be called by thread which was requested to destroy object.
bool IsNormalState()
Return true if object is in normal state.
bool IsParent(Object *obj) const
Checks if specified argument is in the list of object parents.
Reference GetFolder(const std::string &name, bool force=false)
Return folder of specified name, no special symbols allowed.
static bool NameMatch(const std::string &name, const std::string &mask)
Check if name matches to specified mask.
bool AddChild(Object *child, bool withmutex=true)
Add object to list of child objects, thread safe
Reference FindChildRef(const char *name, bool force=false) const
returns reference on child object with given name
bool _IsNormalState()
Same as IsNormalState() but without mutex lock - user should lock mutex himself.
static Reference SearchForChild(Reference &ref, const char *name, bool firsttime, bool force)
bool RemoveChilds(bool cleanup=true)
Remove all childs.
virtual const char * ClassName() const
Returns class name of the object instance.
static void Destroy(Object *obj)
User method for object destroyment.
bool IsNameMatch(const std::string &mask) const
Check if object name match to the mask.
bool AddChildAt(Object *child, unsigned pos, bool withmutex=true)
Add object to list of child objects at specified position.
void SetOwner(bool on=true)
Specifies if object will be owner of its new childs.
bool IsChildsHidden() const
Return true if object wants to hide childs from hierarchy scan, thread safe
static unsigned gNumInstances
actual number of existing instances
bool GetAllChildRef(ReferencesVector *vect) const
virtual bool Find(ConfigIO &cfg)
Method to locate object in xml file.
bool IsLogging() const
Return true if object selected for logging, thread safe
bool IsHidden() const
Return true if object wants to be hidden from hierarchy scan, thread safe
void SetCleanupBit()
Method set cleanup bit that object will be cleaned up in all registered objects Used only by manager ...
void DeleteThis()
Method should be used by the object to delete itself.
void SetName(const char *name)
Changes object name.
unsigned NumChilds() const
returns number of child objects
Object * FindChild(const char *name) const
returns pointer on child object with given name
Object * GetChild(unsigned n) const
returns pointer on child object
Specialized vector with pointers.
Reference on the arbitrary object
void Release()
Releases reference on the object.
bool null() const
Returns true if reference contains nullptr.
Object * fObj
pointer on the object
void Destroy()
Release reference and starts destroyment of referenced object.
Vector of dabc::Reference objects.
Object * FindObject(const char *name, int len=-1) const
Simple search of object by name, no any subfolder structures.
unsigned GetSize() const
Returns number of items in vector.
bool Clear(bool asowner=false)
Clear all references, if owner specified objects will be destroyed.
bool Add(Reference &ref)
Add reference to the vector.
Object * GetObject(unsigned n) const
Returns pointer on the object.
Unlock guard for posix mutex.
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode)
const char * xmlBufferSize
const char * xmlNumOutputs
const char * xmlOutputQueueSize
const char * typeSocketThread
const char * xmlFixedLayout
const char * typeSocketDevice
const char * xmlInputMask
const char * xmlOutputMask
std::string format(const char *fmt,...)
const char * xmlMcastAddr
const char * xmlConnectionNode
const char * xmlAlignment
const char * xmlSignalAttr
const char * xmlUseAcknowledge
const char * xmlFlushTimeout
const char * xmlOutputPrefix
const char * xmlInputQueueSize
const char * xmlCleanupTimeout
const char * xmlInlineDataSize
const char * xmlMemoryPoolNode
const char * xmlNumBuffers
const char * xmlMcastPort
const char * xmlModuleNode
const char * xmlConnTimeout
const char * xmlFileNumber
const char * xmlFileSizeLimit
const char * xmlInputPrefix
const char * xmlMcastRecv
const char * xmlQueueAttr
const char * xmlDeviceNode
const char * xmlThreadNode
const char * xmlNumInputs
const char * typeApplication
Structure used to specify arguments for object constructor.