| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

UpdateManagerSvc.cpp

Go to the documentation of this file.
00001 // $Id: UpdateManagerSvc.cpp,v 1.29 2009/01/23 13:09:15 cattanem Exp $
00002 // Include files
00003 
00004 #include "GaudiKernel/SvcFactory.h"
00005 #include "GaudiKernel/IDetDataSvc.h"
00006 #include "GaudiKernel/IDataProviderSvc.h"
00007 #include "GaudiKernel/IDataManagerSvc.h"
00008 #include "GaudiKernel/IRegistry.h"
00009 #include "GaudiKernel/GaudiException.h"
00010 #include "GaudiKernel/IIncidentSvc.h"
00011 #include "GaudiKernel/IEventProcessor.h"
00012 #include "GaudiKernel/System.h"
00013 
00014 #include "DetDesc/ValidDataObject.h"
00015 #include "DetDesc/Condition.h"
00016 
00017 #include <set>
00018 #include <sstream>
00019 #include <fstream>
00020 #include <memory> // for auto_ptr with gcc 4.3
00021 
00022 // local
00023 #include "UpdateManagerSvc.h"
00024 
00025 #include "ConditionParser.h"
00026 
00027 DECLARE_SERVICE_FACTORY( UpdateManagerSvc );
00028 
00029 //-----------------------------------------------------------------------------
00030 // Implementation file for class : UpdateManagerSvc
00031 //
00032 // 2005-03-30 : Marco Clemencic
00033 //-----------------------------------------------------------------------------
00034 
00035 //=============================================================================
00036 // Standard constructor, initializes variables
00037 //=============================================================================
00038 UpdateManagerSvc::UpdateManagerSvc(const std::string& name, ISvcLocator* svcloc):
00039   Service(name,svcloc), m_dataProvider(NULL),m_detDataSvc(NULL),m_incidentSvc(NULL),m_evtProc(NULL),
00040   m_head_since(1),m_head_until(0)
00041 {
00042 #ifndef WIN32
00043   pthread_mutex_t tmp_lock = PTHREAD_MUTEX_INITIALIZER;
00044   m_busy = tmp_lock;
00045 #endif
00046   declareProperty("DataProviderSvc",    m_dataProviderName = "DetectorDataSvc");
00047   declareProperty("DetDataSvc",         m_detDataSvcName);
00048   declareProperty("ConditionsOverride", m_conditionsOveridesDesc);
00049   declareProperty("DiaDumpFile",        m_diaDumpFile = "");
00050 }
00051 //=============================================================================
00052 // Destructor
00053 //=============================================================================
00054 UpdateManagerSvc::~UpdateManagerSvc() {
00055   // delete objects in the container
00056   for (Item::ItemList::const_iterator i = m_all_items.begin(); i != m_all_items.end(); ++i){
00057     delete *i;
00058   }
00059 }
00060 
00061 //=============================================================================
00062 // IInterface implementation
00063 //=============================================================================
00064 StatusCode UpdateManagerSvc::queryInterface(const InterfaceID& riid, void** ppvUnknown){
00065   if ( IUpdateManagerSvc::interfaceID().versionMatch(riid) ) {
00066     *ppvUnknown = (IUpdateManagerSvc*)this;
00067     addRef();
00068     return StatusCode::SUCCESS;
00069   } else if ( IIncidentListener::interfaceID().versionMatch(riid) ) {
00070     *ppvUnknown = (IIncidentListener*)this;
00071     addRef();
00072     return StatusCode::SUCCESS;
00073   }
00074   return Service::queryInterface(riid,ppvUnknown);
00075 }
00076 
00077 //=============================================================================
00078 // IService implementation
00079 //=============================================================================
00080 StatusCode UpdateManagerSvc::initialize(){
00081   // base class initialization
00082   StatusCode sc = Service::initialize();
00083   if (!sc.isSuccess()) return sc;
00084   // local initialization
00085   MsgStream log(msgSvc(),name());
00086   log << MSG::DEBUG << "--- initialize ---" << endmsg;
00087 
00088   // find the data provider
00089   sc = serviceLocator()->service<IDataProviderSvc>(m_dataProviderName,m_dataProvider,true);
00090   if (!sc.isSuccess()) {
00091     log << MSG::ERROR << "Unable to get a handle to the data provider" << endmsg;
00092     return sc;
00093   } else {
00094     log << MSG::DEBUG << "Got pointer to IDataProviderSvc \"" << m_dataProviderName << '"' << endmsg;
00095     IDataManagerSvc * dMgr;
00096     sc = m_dataProvider->queryInterface(IDataManagerSvc::interfaceID(),(void **) &dMgr);
00097     if ( sc.isSuccess() ) {
00098       m_dataProviderRootName = dMgr->rootName() + "/";
00099       dMgr->release();
00100       if (!sc.isSuccess()) {
00101         return sc;
00102       }
00103     }
00104     else {
00105       log << MSG::WARNING << "Cannot access IDataManagerSvc interface of \"" << m_dataProviderName
00106           << "\": using empty RootName" << endmsg;
00107       m_dataProviderRootName = "";
00108     }
00109   }
00110 
00111   // find the detector data service
00112   if (m_detDataSvcName == "") m_detDataSvcName = m_dataProviderName;
00113   sc = serviceLocator()->service(m_detDataSvcName,m_detDataSvc,true);
00114   if (!sc.isSuccess()) {
00115     log << MSG::WARNING << "Unable to get a handle to the detector data service interface:"
00116       " all the calls to newEvent(void) will fail!" << endmsg;
00117     m_detDataSvc = NULL;
00118   } else {
00119     log << MSG::DEBUG << "Got pointer to IDetDataSvc \"" << m_detDataSvcName << '"' << endmsg;
00120   }
00121 
00122   // before registering to the incident service I have to be sure that the EventClockSvc is ready
00123   IService *evtClockSvc;
00124   sc = service("EventClockSvc", evtClockSvc, true);
00125   if ( sc.isSuccess() ) {
00126     log << MSG::DEBUG << "Good: EventClockSvc found" << endmsg;
00127     evtClockSvc->release();
00128   } else {
00129     log << MSG::WARNING << "Unable find EventClockSvc, probably I'll not work." << endmsg;
00130   }
00131 
00132   // register to the incident service for BeginEvent incidents
00133   sc = service("IncidentSvc", m_incidentSvc, false);
00134   if ( sc.isSuccess() ) {
00135     m_incidentSvc->addListener(this,IncidentType::BeginEvent);
00136     log << MSG::DEBUG << "Got pointer to IncidentSvc" << endmsg;
00137   } else {
00138     log << MSG::ERROR << "Unable to register to the incident service." << endmsg;
00139     m_incidentSvc = NULL;
00140     return sc;
00141   }
00142 
00143   sc = serviceLocator()->service("ApplicationMgr",m_evtProc);
00144   if ( !sc.isSuccess() ) {
00145     log << MSG::ERROR << "Cannot find an event processor." << endmsg;
00146     return sc;
00147   }
00148 
00149   // Loop over overridden conditions
00150   for ( std::vector<std::string>::iterator co = m_conditionsOveridesDesc.begin();
00151         co != m_conditionsOveridesDesc.end(); ++co ) {
00152     std::string name;
00153     Condition *cond = new Condition();
00154     if (ConditionParser(*co,name,*cond)) {
00155 
00156       // Remove TS root name from the path
00157       if ( name[0] == '/'
00158            && name.compare(0,m_dataProviderRootName.size(),m_dataProviderRootName) == 0 ){
00159         name.erase(0,m_dataProviderRootName.size());
00160       }
00161 
00162       // If a condition override with that name already exists, delete it
00163       Condition * dest = m_conditionsOverides[name];
00164       if ( dest ) {
00165         log << MSG::WARNING << "Override condition for path '" << name
00166             << "' is defined more than once (I use the last one)." << endmsg;
00167         delete dest;
00168       }
00169 
00170       // Add the condition to internal list
00171       m_conditionsOverides[name] = cond;
00172       log << MSG::DEBUG << "Added condition: " << name << "\n" << cond->printParams() << endmsg;
00173 
00174     } else {
00175       // something went wrong while parsing: delete the temporary
00176       delete cond;
00177       log << MSG::ERROR << "Cannot understand condition:" << endmsg;
00178       log << MSG::ERROR << *co << endmsg;
00179       return StatusCode::FAILURE;
00180     }
00181   }
00182 
00183   return StatusCode::SUCCESS;
00184 }
00185 
00186 StatusCode UpdateManagerSvc::finalize(){
00187   // local finalization
00188 
00189   MsgStream log(msgSvc(),name());
00190   log << MSG::DEBUG << "--- finalize ---" << endmsg;
00191 
00192   if ( m_outputLevel <= MSG::DEBUG || ! m_diaDumpFile.empty() ) dump();
00193 
00194   // release the interfaces used
00195   if (m_dataProvider != NULL) m_dataProvider->release();
00196   if (m_detDataSvc != NULL) m_detDataSvc->release();
00197   if (m_incidentSvc != NULL) {
00198     // unregister from the incident svc
00199     m_incidentSvc->removeListener(this,IncidentType::BeginEvent);
00200     m_incidentSvc->release();
00201   }
00202   if (m_evtProc != NULL) m_evtProc->release();
00203 
00204   // delete unused overridden conditions (the others are deleted together with the T.S.)
00205   if ( ! m_conditionsOverides.empty() ) {
00206     log << MSG::WARNING << "Few overrided conditions were not used:" << endmsg;
00207     for (GaudiUtils::Map<std::string,Condition*>::iterator c = m_conditionsOverides.begin();
00208          c != m_conditionsOverides.end(); ++c ) {
00209       log << MSG::WARNING << c->first << endmsg;
00210       delete c->second;
00211     }
00212   }
00213 
00214   // base class finalization
00215   return Service::finalize();
00216 }
00217 //=============================================================================
00218 // IUpdateManagerSvc implementation
00219 //=============================================================================
00220 IDataProviderSvc *UpdateManagerSvc::dataProvider() const {
00221   return m_dataProvider;
00222 }
00223 IDetDataSvc *UpdateManagerSvc::detDataSvc() const {
00224   return m_detDataSvc;
00225 }
00226 void UpdateManagerSvc::i_registerCondition(const std::string &condition, BaseObjectMemberFunction *mf,
00227                                            BasePtrSetter *ptr_dest){
00228   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00229     throw GaudiException("Service offline","UpdateManagerSvc::registerCondition",StatusCode::FAILURE);
00230   }
00231 
00232   MsgStream log(msgSvc(),name());
00233 
00234   std::string cond_copy(condition);
00235 
00236   if (!cond_copy.empty()) {
00237     // remove the root name if present
00238     if ( cond_copy[0] == '/'
00239          && cond_copy.compare(0,m_dataProviderRootName.size(),m_dataProviderRootName) == 0 ){
00240       cond_copy.erase(0,m_dataProviderRootName.size());
00241     }
00242     log << MSG::DEBUG << "registering condition \"" << cond_copy
00243         << "\" for object of type " << System::typeinfoName(mf->type()) << " at " << std::hex << mf->castToVoid() << endmsg;
00244   }
00245   else {
00246     log << MSG::DEBUG << "registering object of type " << System::typeinfoName(mf->type())
00247         << " (without condition)" << endmsg;
00248   }
00249 
00250   // find the object
00251   Item *mf_item = findItem(mf);
00252   if (!mf_item){ // a new OMF
00253     mf_item = new Item(mf, m_dataProviderRootName);
00254     m_all_items.push_back(mf_item);
00255     m_head_items.push_back(mf_item); // since it is new, it has no parents
00256     insertInMap( mf_item );
00257  } else {
00258     if ( ! mf_item->ptr ) { // the item is know but not its pointer (e.g. after a purge)
00259       mf_item->vdo = mf->castToValidDataObject();
00260       mf_item->ptr = mf->castToVoid();
00261     }
00262   }
00263 
00264   if (!cond_copy.empty()) {
00265     // find the condition
00266     Item *cond_item = findItem(cond_copy);
00267     if (!cond_item){ // a new condition
00268 
00269       // Check if the requested condition is in the override list.
00270       GaudiUtils::Map<std::string,Condition*>::iterator cond_ov = m_conditionsOverides.find(cond_copy);
00271       if ( cond_ov != m_conditionsOverides.end() ) {
00272         // yes, it is!
00273         cond_item = new Item(cond_copy,Item::UserPtrType(ptr_dest,mf_item->ptr),
00274                              cond_ov->second);
00275         // I do not need it anymore in the list
00276         m_conditionsOverides.erase(cond_ov);
00277       } else {
00278         // no override
00279         cond_item = new Item(cond_copy,Item::UserPtrType(ptr_dest,mf_item->ptr));
00280       }
00281 
00282       m_all_items.push_back(cond_item);
00283       insertInMap( cond_item );
00284     } else {
00285       if (ptr_dest){
00286         // I already have this condition registered, but a new user wants to set the pointer to it.
00287         cond_item->user_dest_ptrs.push_back(Item::UserPtrType(ptr_dest,mf_item->ptr));
00288         // Let's check if the object is already loaded (the pointers are set by Item only when it loads them)
00289         if (cond_item->vdo) {
00290           ptr_dest->set(cond_item->vdo);
00291           if ( ptr_dest->isNull() ) { // the dynamic cast failed
00292             throw GaudiException("A condition in memory cannot be casted to the requested type",
00293                 "UpdateManagerSvc::i_registerCondition", StatusCode::FAILURE );
00294           }
00295         }
00296       }
00297       if (cond_item->isHead()) removeFromHead(cond_item);
00298     }
00299     link(mf_item,mf,cond_item);
00300   } else {
00301     // this is usually done inside Item::addChild (called by "link")
00302     Item::MembFuncList::iterator mfIt = mf_item->find(mf);
00303     if (mfIt == mf_item->memFuncs.end()) {
00304       // I do not have the MF registered inside the item
00305       // so I add it
00306       mf_item->memFuncs.insert(mfIt,Item::MembFunc(mf));
00307     } else {
00308       // the MF is already there
00309       if (mfIt->mf != mf) // but it has a different pointer
00310         // so I do not need to keep the copy I have
00311         delete mf;
00312     }
00313     // Since we are not using a condition, the user pointer setter is not needed
00314     // nor used, so we must delete it.
00315     if (ptr_dest) delete ptr_dest;
00316   }
00317   // a new item means that we need an update
00318   m_head_since = 1;
00319   m_head_until = 0;
00320 }
00321 void UpdateManagerSvc::i_registerCondition(void *obj, BaseObjectMemberFunction *mf){
00322   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00323     throw GaudiException("Service offline","UpdateManagerSvc::registerCondition",StatusCode::FAILURE);
00324   }
00325   MsgStream log(msgSvc(),name());
00326   log << MSG::DEBUG << "registering object at " << std::hex << obj << std::dec
00327       << " for object of type " << System::typeinfoName(mf->type()) << " at " << std::hex << mf->castToVoid() << endmsg;
00328   // find the "condition"
00329   Item *cond_item = findItem(obj);
00330   if (!cond_item){ // Error!!!
00331     throw UpdateManagerException("tried to register for an object not in the UpdateManagerSvc");
00332   } else {
00333     if (cond_item->isHead()) removeFromHead(cond_item);
00334   }
00335   // find the OMF (Object Member Function)
00336   Item *mf_item = findItem(mf);
00337   if (!mf_item){ // a new OMF
00338     mf_item = new Item(mf, m_dataProviderRootName);
00339     m_all_items.push_back(mf_item);
00340     m_head_items.push_back(mf_item); // since it is new, it has no parents
00341     insertInMap( mf_item );
00342   }
00343   if ( ! mf_item->ptr ) { // the item is know but not its pointer (e.g. after a purge)
00344     mf_item->vdo = mf->castToValidDataObject();
00345     mf_item->ptr = mf->castToVoid();
00346   }
00347   link(mf_item,mf,cond_item);
00348   // a new item means that we need an update
00349   m_head_since = 1;
00350   m_head_until = 0;
00351 }
00352 StatusCode UpdateManagerSvc::newEvent(){
00353   if (detDataSvc() != NULL){
00354     if (detDataSvc()->validEventTime()) {
00355       return newEvent(detDataSvc()->eventTime());
00356     } else {
00357       MsgStream log(msgSvc(),name());
00358       log << MSG::WARNING << "newEvent(): the event time is not defined!" << endmsg;
00359     }
00360   }
00361   return StatusCode::FAILURE;
00362 }
00363 StatusCode UpdateManagerSvc::newEvent(const Gaudi::Time &evtTime){
00364   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00365     throw GaudiException("Service offline","UpdateManagerSvc::newEvent",StatusCode::FAILURE);
00366   }
00367 
00368   StatusCode sc = StatusCode::SUCCESS;
00369 
00370 #ifndef WIN32
00371   MsgStream log(msgSvc(),name());
00372 
00373   log << MSG::VERBOSE << "newEvent(evtTime): acquiring mutex lock" << endmsg;
00374   acquireLock();
00375 #endif
00376 
00377   // Check head validity
00378   if ( evtTime >= m_head_since && evtTime < m_head_until ) {
00379 #ifndef WIN32
00380     log << MSG::VERBOSE << "newEvent(evtTime): releasing mutex lock" << endmsg;
00381     releaseLock();
00382 #endif
00383     return sc; // no need to update
00384   }
00385 
00386 #ifndef WIN32
00387   try {
00388 #endif
00389   Item::ItemList::iterator it;
00390 
00391   // The head list may change while updating, I'll loop until it's stable (or a problem occurs)
00392   bool head_has_changed = false;
00393   do {
00394     if ( m_outputLevel <= MSG::DEBUG ) {
00395       MsgStream log(msgSvc(),name());
00396       log << MSG::DEBUG << "newEvent(evtTime): loop over head items" << endmsg;
00397     }
00398     // first I make a copy of the current head
00399     Item::ItemList head_copy(m_head_items);
00400     // Start from a clean IOV (I cannot use m_head_X because the head is not stable and they may change)
00401     Gaudi::Time head_copy_since(Gaudi::Time::epoch());
00402     Gaudi::Time head_copy_until(Gaudi::Time::max());
00403     for (it = head_copy.begin(); it != head_copy.end() && sc.isSuccess(); ++it){
00404       if ( m_outputLevel <= MSG::DEBUG ) {
00405         MsgStream item_log(msgSvc(),name()+"::Item");
00406         sc = (*it)->update(dataProvider(),evtTime,&item_log);
00407       } else {
00408         sc = (*it)->update(dataProvider(),evtTime);
00409       }
00410       if (sc.isSuccess()) {
00411         if ( head_copy_since < (*it)->since )  head_copy_since = (*it)->since;
00412         if ( head_copy_until > (*it)->until )  head_copy_until = (*it)->until;
00413       }
00414     }
00415     // now it is safe to set m_head_X
00416     m_head_since = head_copy_since;
00417     m_head_until = head_copy_until;
00418 
00419     // check if we need to re-do the loop (success and a change in the head)
00420     head_has_changed = sc.isSuccess() && (head_copy != m_head_items);
00421   } while ( head_has_changed );
00422 
00423 #ifndef WIN32
00424   } catch (...) {
00425     log << MSG::VERBOSE << "newEvent(evtTime): releasing mutex lock (exception occurred)" << endmsg;
00426     releaseLock();
00427     throw;
00428   }
00429 
00430   log << MSG::VERBOSE << "newEvent(evtTime): releasing mutex lock" << endmsg;
00431   releaseLock();
00432 #endif
00433 
00434   return sc;
00435 }
00436 StatusCode UpdateManagerSvc::i_update(void *instance){
00437   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00438     throw GaudiException("Service offline","UpdateManagerSvc::update",StatusCode::FAILURE);
00439   }
00440 
00441   if ( m_outputLevel <= MSG::DEBUG ) {
00442     MsgStream log(msgSvc(),name());
00443     log << MSG::DEBUG << "Update specific object at " << instance << endmsg;
00444   }
00445   if (detDataSvc() != NULL){
00446     if (detDataSvc()->validEventTime()) {
00447       Item *item = findItem(instance);
00448       if (item) {
00449         StatusCode sc;
00450         if ( m_outputLevel <= MSG::DEBUG ) {
00451           MsgStream item_log(msgSvc(),name()+"::Item");
00452           sc = item->update(dataProvider(),detDataSvc()->eventTime(),&item_log);
00453         } else {
00454           sc = item->update(dataProvider(),detDataSvc()->eventTime());
00455         }
00456         if (sc.isSuccess()) {
00457           if ( m_head_since < item->since )  m_head_since = item->since;
00458           if ( m_head_until > item->until )  m_head_until = item->until;
00459         }
00460         return sc;
00461       } else {
00462         MsgStream log(msgSvc(),name());
00463         log << MSG::WARNING << "Cannot find object at " << instance << endmsg;
00464       }
00465     } else {
00466       return StatusCode::SUCCESS;
00467     }
00468   }
00469   return StatusCode::FAILURE;
00470 }
00471 void UpdateManagerSvc::i_invalidate(void *instance){
00472   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00473     throw GaudiException("Service not initialized","UpdateManagerSvc::invalidate",StatusCode::FAILURE);
00474   }
00475 
00476   if ( m_outputLevel <= MSG::DEBUG ) {
00477     MsgStream log(msgSvc(),name());
00478     log << MSG::DEBUG << "Invalidate object at " << instance << endmsg;
00479   }
00480   Item *item = findItem(instance);
00481   if (item) {
00482     item->invalidate();
00483     m_head_since = 1;
00484     m_head_until = 0;
00485   } else {
00486     MsgStream log(msgSvc(),name());
00487     log << MSG::WARNING << "Cannot find object at " << instance << endmsg;
00488   }
00489 }
00490 
00491 void UpdateManagerSvc::unlink(Item *parent, Item *child){
00492 
00493   // check if the parent knows about the child
00494   Item::ItemList::iterator childIt = std::find(parent->children.begin(),
00495                                                parent->children.end(),child);
00496   if ( parent->children.end() == childIt )
00497     return; // parent does not know about child
00498 
00499   // remove from child all the user pointers belonging to the parent
00500   Item::UserPtrList::iterator pi = child->user_dest_ptrs.begin();
00501   while ( pi != child->user_dest_ptrs.end() ) {
00502     if (pi->second != parent) {
00503       pi = child->user_dest_ptrs.erase(pi);
00504     } else {
00505       ++pi;
00506     }
00507   }
00508 
00509   // If the child is used by a MF that uses other Items, we need to disconnect
00510   // them too.
00511   std::set<Item*> siblings; // list of Items used together with "child"
00512 
00513   // loop over child parent's pairs (mf,parent) to disconnect from them
00514   Item::MembFuncList::iterator p_mf;
00515   Item::ParentList::iterator p = child->parents.begin();
00516   while ( p != child->parents.end() ) {
00517     if (p->first != parent) {
00518       ++p;
00519       continue; // skip to next one
00520     }
00521 
00522     // find the MF inside the parent
00523     p_mf = parent->find(p->second);
00524 
00525     // find iterator to child in MF list ...
00526     Item::ItemList *mfInternalList = p_mf->items;
00527     Item::ItemList::iterator entry = std::find(mfInternalList->begin(),
00528                                                mfInternalList->end(),child);
00529     // ... and remove it (if found)
00530     if ( mfInternalList->end() != entry )
00531       mfInternalList->erase(entry);
00532 
00533     // append then other Items in the MF (to unlink them too)
00534     siblings.insert(mfInternalList->begin(),mfInternalList->end());
00535 
00536     // remove the parent pair from child
00537     p = child->parents.erase(p);
00538   }
00539 
00540   // unlink the siblings
00541   std::set<Item*>::iterator s;
00542   for ( s = siblings.begin(); s != siblings.end(); ++s ) {
00543     unlink(parent,*s);
00544   }
00545 
00546   // Check in the parent if there are MF without children: they have to be
00547   // removed.
00548   p_mf = parent->memFuncs.begin();
00549   while ( p_mf != parent->memFuncs.end() ) {
00550     if ( p_mf->items->empty() ) p_mf = parent->memFuncs.erase(p_mf);
00551     else ++p_mf;
00552   }
00553 
00554   // Remove child from parent's list of all children.
00555   // we have to look again for it because the iterator may have been made
00556   // invalid by the "unlink" of siblings
00557   childIt = std::find(parent->children.begin(),
00558                       parent->children.end(),child);
00559   if (childIt != parent->children.end())
00560     parent->children.erase(childIt);
00561 
00562   // check if the child should be part of the head now
00563   if ( child->isHead() ) {
00564     m_head_items.push_back(child);
00565   }
00566 
00567   // Note: I do not need to touch the validity because the it can only increase
00568 
00569 }
00570 
00571 void UpdateManagerSvc::i_unregister(void *instance){
00572   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00573     // un-registration is allowed after service finalize (no-op).
00574     if ( m_outputLevel <= MSG::VERBOSE ) {
00575       MsgStream log(msgSvc(),name());
00576       log << MSG::VERBOSE << "Trying to unregister object at " << instance
00577           << ", with the service OFFLINE"<< endmsg;
00578     }
00579     return;
00580   }
00581 
00582   if ( m_outputLevel <= MSG::DEBUG ) {
00583     MsgStream log(msgSvc(),name());
00584     log << MSG::DEBUG << "Unregister object at " << instance << endmsg;
00585   }
00586 
00587   Item *item = findItem(instance);
00588   if (item){
00589 
00590     // unlink from parents
00591     Item::ParentList::iterator p = item->parents.begin();
00592     while ( p != item->parents.end() ) {
00593       unlink(p->first,item);
00594       p = item->parents.begin();
00595     }
00596 
00597     // unlink from children
00598     Item::ItemList::iterator c = item->children.begin();
00599     while ( c != item->children.end() ) {
00600       unlink(item,(*c));
00601       c = item->children.begin();
00602     }
00603 
00604     // update the lists of Items
00605     if ( item->isHead() ) removeFromHead(item);
00606     m_all_items.erase(std::find(m_all_items.begin(),m_all_items.end(),item));
00607 
00608     // The erased item shoud also disappear from the maps, if this is the last for this key, i.e. isHead
00609     m_pathMap.erase( item->path );
00610 
00611     // finally we can delete the Item
00612     delete item;
00613   }
00614 }
00615 
00616 void UpdateManagerSvc::dump(){
00617   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00618     throw GaudiException("Service offline","UpdateManagerSvc::dump",StatusCode::FAILURE);
00619   }
00620 
00621   MsgStream log(msgSvc(),name());
00622 
00623   std::auto_ptr<std::ofstream> dia_file;
00624   int dia_lines_ctr = 0;
00625   if ( ! m_diaDumpFile.empty() ){
00626     dia_file.reset(new std::ofstream(m_diaDumpFile.c_str()));
00627   }
00628 
00629   if (dia_file.get() != NULL) {
00630     // DIA header
00631     (*dia_file)
00632       << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
00633       << "<dia:diagram xmlns:dia=\"http://www.lysator.liu.se/~alla/dia/\">"
00634       << "<dia:layer name=\"Background\" visible=\"true\">";
00635   }
00636 
00637   log << MSG::DEBUG << "--- Dump" << endmsg;
00638   log << MSG::DEBUG << "    " << m_all_items.size() << " items registered" << endmsg;
00639   log << MSG::DEBUG << "     of which " << m_head_items.size() << " in the head" << endmsg;
00640   log << MSG::DEBUG << "         head IOV = " << m_head_since << " - " << m_head_until << endmsg;
00641 
00642   size_t cnt = 0, head_cnt = 0;
00643   for (Item::ItemList::iterator i = m_all_items.begin(); i != m_all_items.end(); ++i){
00644     log << MSG::DEBUG << "--item " << cnt++ << " " << std::hex << *i << std::dec;
00645     if ((*i)->isHead()){
00646       log << " (head)";
00647       ++head_cnt;
00648     }
00649     log << endmsg;
00650 
00651     if (dia_file.get() != NULL) {
00652       // DIA Object for registered item (first part)
00653       (*dia_file)
00654         << "<dia:object type=\"Flowchart - Box\" version=\"0\""
00655         << " id=\"i" << std::hex << *i << "\">"
00656         << "<dia:attribute name=\"text\"><dia:composite type=\"text\">"
00657         << "<dia:attribute name=\"string\"><dia:string>#"
00658         << "(" << std::dec << cnt-1 << ") " << std::hex << *i << "\n"
00659         << "(" << (*i)->ptr << ")";
00660     }
00661 
00662     log << MSG::DEBUG << "       ptr  = " << std::hex << (*i)->ptr << std::dec << endmsg;
00663     if ( !(*i)->path.empty() ) {
00664       log << MSG::DEBUG << "       path = " << (*i)->path << endmsg;
00665       if (dia_file.get() != NULL) {
00666         // If we have the path, we can put it in the DIA Object
00667         (*dia_file) << "\n" << (*i)->path;
00668       }
00669     }
00670 
00671     if (dia_file.get() != NULL) {
00672       // DIA Object for registered item (closure)
00673       (*dia_file) << "#</dia:string></dia:attribute></dia:composite>"
00674                   << "</dia:attribute></dia:object>";
00675     }
00676 
00677     log << MSG::DEBUG << "        IOV = " << (*i)->since << " - " << (*i)->until << endmsg;
00678     if ((*i)->memFuncs.size()){
00679       log << MSG::DEBUG << "       depend on :" << endmsg;
00680       for (Item::MembFuncList::iterator mfIt = (*i)->memFuncs.begin(); mfIt != (*i)->memFuncs.end(); ++mfIt){
00681         log << MSG::DEBUG << std::hex << "                  ";
00682         for (Item::ItemList::iterator itemIt = mfIt->items->begin(); itemIt != mfIt->items->end(); ++itemIt){
00683           log << " " << *itemIt;
00684           if (dia_file.get() != NULL) {
00685             // Add an arrow to the diagram connecting the user Item to the
00686             // used Item
00687             (*dia_file)
00688               << "<dia:object type=\"Standard - Line\" version=\"0\" id=\"l" << std::dec << dia_lines_ctr++ << "\">"
00689               << "<dia:attribute name=\"end_arrow\"><dia:enum val=\"22\"/>"
00690               << "</dia:attribute>"
00691               << "<dia:connections>"
00692               << "<dia:connection handle=\"0\" to=\"i" << std::hex << *i << "\" connection=\"13\"/>"
00693               << "<dia:connection handle=\"1\" to=\"i" << std::hex << *itemIt << "\" connection=\"2\"/>"
00694               << "</dia:connections></dia:object>";
00695           }
00696         }
00697         log << std::dec << endmsg;
00698       }
00699     }
00700   }
00701 
00702   if (dia_file.get() != NULL) {
00703     // DIA header
00704     (*dia_file) << "</dia:layer></dia:diagram>\n";
00705     log << MSG::ALWAYS << "DIA file '" << m_diaDumpFile << "' written" << endmsg;
00706   }
00707 
00708   log << MSG::DEBUG << "Found " << head_cnt << " head items: ";
00709   if (m_head_items.size() == head_cnt){
00710     log << "OK";
00711   } else {
00712     log << "MISMATCH!!!!!";
00713   }
00714   log << endmsg;
00715 }
00716 
00717 
00718 void UpdateManagerSvc::purge() {
00719   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00720     throw GaudiException("Service offline","UpdateManagerSvc::purge",StatusCode::FAILURE);
00721   }
00722 
00723   MsgStream log(msgSvc(),name());
00724 
00725   log << MSG::INFO << "Purging dependencies network" << endmsg;
00726 
00727   // first I make a copy of the list of objects
00728   //Item::ItemList items_copy(m_all_items);
00729   //Item::ItemList items_copy(m_head_items);
00730   // Start from a clean IOV (I cannot use m_head_X because the head is not stable and they may change)
00731   //Gaudi::Time head_copy_since(Gaudi::Time::epoch());
00732   //Gaudi::Time head_copy_until(Gaudi::Time::max());
00733 
00734   Item::ItemList::iterator it = m_all_items.begin();
00735   for (it = m_all_items.begin(); it != m_all_items.end() ; ++it){
00736     (*it)->purge(&log);
00737 
00738     if ( ! (*it)->path.empty() ) {
00739       Item::ItemList &children = (*it)->children;
00740       // remove connections to children if the object is going to be reloaded
00741       Item::ItemList::iterator c = children.begin();
00742       while ( children.end() != c ) {
00743         unlink(*it,*c);
00744         c = children.begin();
00745       }
00746     }
00747   }
00748 
00749   m_head_since = 1;
00750   m_head_until = 0;
00751 
00752 }
00753 
00754 //=========================================================================
00755 //  search the item with the given path and get its validity
00756 //=========================================================================
00757 bool UpdateManagerSvc::getValidity(const std::string path, Gaudi::Time& since, Gaudi::Time &until,
00758                                    bool path_to_db) {
00759   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00760     throw GaudiException("Service offline","UpdateManagerSvc::registerCondition",StatusCode::FAILURE);
00761   }
00762   // search
00763   Item *item = findItem(path,path_to_db);
00764   if (item) {
00765     // copy IOV limits
00766     since = item->since;
00767     until = item->until;
00768     return true;
00769   }
00770   return false;
00771 }
00772 //=========================================================================
00773 //  search the item with the given path and change its validity
00774 //=========================================================================
00775 void UpdateManagerSvc::setValidity(const std::string path, const Gaudi::Time& since, const Gaudi::Time &until,
00776                                    bool path_to_db) {
00777   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ){
00778     throw GaudiException("Service offline","UpdateManagerSvc::registerCondition",StatusCode::FAILURE);
00779   }
00780 
00781   if (!path_to_db) { // the DDS path is unique
00782     // search
00783     Item *item = findItem(path,path_to_db);
00784     if (item) {
00785       // set the validity and propagate up
00786       item->changeValidity(since,until);
00787       // if the object has already been loaded we should also change its validity
00788       if (item->vdo) item->vdo->setValidity(since,until);
00789     }
00790   } else { // a CondDB path can contain many objects
00791     Item::ItemList::iterator i = m_all_items.begin();
00792     while ( i !=  m_all_items.end() ) {
00793       if ( (*i)->match(path,path_to_db) ) {
00794         // set the validity and propagate up
00795         (*i)->changeValidity(since,until);
00796         // if the object has already been loaded we should also change its validity
00797         if ((*i)->vdo) (*i)->vdo->setValidity(since,until);
00798       }
00799       ++i;
00800     }
00801   }
00802   // adjust head validity
00803   if ( m_head_since < since ) m_head_since = since;
00804   if ( m_head_until > until ) m_head_until = until;
00805 }
00806 
00807 //=========================================================================
00808 //  Handle BeginEvent incident
00809 //=========================================================================
00810 void UpdateManagerSvc::handle(const Incident &inc) {
00811   if ( inc.type() == IncidentType::BeginEvent ) {
00812     MsgStream log( msgSvc(), name() );
00813     log << MSG::DEBUG << "New BeginEvent incident received" << endmsg;
00814     StatusCode sc = UpdateManagerSvc::newEvent();
00815     if (!sc.isSuccess()) {
00816       log << MSG::FATAL << "***** The update failed. I schedule a stop of the run *****" << endmsg;
00817       m_evtProc->stopRun();
00818       // The exception is ignored by the IncidentSvc
00819       // throw UpdateManagerException("Failed to preform the update","*UpdateManagerSvc*",sc);
00820     }
00821   }
00822 }
00823 
00824 //=========================================================================
00825 //  Locking functionalities
00826 //=========================================================================
00827 void UpdateManagerSvc::acquireLock(){
00828 #ifndef WIN32
00829   pthread_mutex_lock(&m_busy);
00830 #endif
00831 }
00832 void UpdateManagerSvc::releaseLock(){
00833 #ifndef WIN32
00834   pthread_mutex_unlock(&m_busy);
00835 #endif
00836 }
00837 
00838 //=============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:02:42 2011 for DetDescSvc by doxygen 1.4.7