#include #include #include #include #include #include "IHandle.hxx" #include "IHandleHack.hxx" #include "ICOMETLog.hxx" namespace { int gHandleBaseCount = 0; int gLastHandleCount = 0; std::set *gHandleSet = NULL; } ClassImp(COMET::IHandleBase); COMET::IHandleBase::IHandleBase() : fCount(0) { ++gHandleBaseCount; if (gHandleSet) gHandleSet->insert(this); } COMET::IHandleBase::~IHandleBase() { --gHandleBaseCount; if (gHandleSet) gHandleSet->erase(this); } ClassImp(COMET::IHandleBaseDeletable); COMET::IHandleBaseDeletable::IHandleBaseDeletable() : fObject(NULL) { } COMET::IHandleBaseDeletable::IHandleBaseDeletable(TObject* pointee) : fObject(pointee) { } COMET::IHandleBaseDeletable::~IHandleBaseDeletable() { if (!fObject) return; // Actually delete the object. if (IsOwner()) delete fObject; } ClassImp(COMET::IHandleBaseUndeletable); COMET::IHandleBaseUndeletable::IHandleBaseUndeletable() : fObject(NULL) { } COMET::IHandleBaseUndeletable::IHandleBaseUndeletable(TObject* pointee) : fObject(pointee) { } COMET::IHandleBaseUndeletable::~IHandleBaseUndeletable() { // Absolutely nothing to do. } bool COMET::CleanHandleRegistry(bool) { bool result = (gHandleBaseCount==gLastHandleCount); if (!result) { COMETLog("CleanHandleRegistry::" << " Handle Count: " << gHandleBaseCount << " Change: " << gHandleBaseCount - gLastHandleCount); gLastHandleCount = gHandleBaseCount; } return result; } void COMET::DumpHandleRegistry() { if (!gHandleSet) return; if (gHandleSet->empty()) return; COMETLog("Existing handles: " << gHandleSet->size()); COMET::ICOMETLog::IncreaseIndentation(); for (std::set::iterator h = gHandleSet->begin(); h != gHandleSet->end(); ++h) { COMET::IHandleBase* handleBase = *h; COMETLog(std::hex << "(0x" << handleBase << ")"); if (handleBase) { COMET::ICOMETLog::IncreaseIndentation(); TObject *object = handleBase->GetObject(); COMETLog(std::hex << "-> (0x" << object << ")"); if (object) { COMET::ICOMETLog::IncreaseIndentation(); COMETLog("Class: " << object->ClassName()); COMETLog("Name: " << object->GetName()); COMET::ICOMETLog::DecreaseIndentation(); if (COMET::ICOMETLog::GetDebugLevel()>COMET::ICOMETLog::ErrorLevel) { object->ls(); } } COMET::ICOMETLog::DecreaseIndentation(); } } COMET::ICOMETLog::DecreaseIndentation(); } void COMET::EnableHandleRegistry(bool enable) { if (enable && !gHandleSet) { COMETLog("Enable the handle registry"); gHandleSet = new std::set; } else { COMETLog("Disable the handle registry"); delete gHandleSet; gHandleSet = NULL; } } ClassImp(COMET::IVHandle); COMET::IVHandle::IVHandle() {Default(NULL);} COMET::IVHandle::~IVHandle() {} void COMET::IVHandle::Default(COMET::IHandleBase* handle) { fHandle = handle; if (fHandle) fHandle->IncrementReferenceCount(); } void COMET::IVHandle::Link(const COMET::IVHandle& rhs) { // Copy the handle. fHandle = rhs.fHandle; // Increment the reference count if (fHandle) fHandle->IncrementReferenceCount(); } bool COMET::IVHandle::Unlink() { if (!fHandle) return false; fHandle->DecrementReferenceCount(); if (fHandle->GetReferenceCount() < 1) return true; return false; } void COMET::IVHandle::Destroy(void) { // Save the value of the handle COMET::IHandleBase* target = fHandle; // But, mark the current object as invalid. fHandle = NULL; // Is the target a valid handle? if (!target) return; // Try to delete the object. The target is a IHandleBase and its // distructor will decide if the object is deletable. delete target; } TObject* COMET::IVHandle::GetPointerValue() const { if (!fHandle) return NULL; return fHandle->GetObject(); } void COMET::IVHandle::Release(void) { if (!fHandle) return; fHandle->Release(); } bool COMET::IVHandle::operator == (const COMET::IVHandle& rhs) const { if (fHandle == rhs.fHandle) return true; return fHandle && (fHandle->GetObject() == rhs.fHandle->GetObject()); } void COMET::IVHandle::ls(Option_t *opt) const { TROOT::IndentLevel(); std::cout << ClassName() << "(" << this << "):: "; if (strstr(opt,"size")) { TClass* cls = Class(); if (!cls) return; std::cout << " (" << cls->Size() << " b)"; } if (fHandle) { std::cout << " Refs: " << fHandle->GetReferenceCount(); if (fHandle->IsOwner()) std::cout << " (owner)"; else std::cout << " (released)"; } std::cout << std::endl; TROOT::IncreaseDirLevel(); const TObject* ptr = GetPointerValue(); if (ptr) ptr->ls(opt); TROOT::DecreaseDirLevel(); }