Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

IoComponentMgr.cpp

Go to the documentation of this file.
00001 
00002 // IoComponentMgr.cxx
00003 // Implementation file for class IoComponentMgr
00004 // Author: S.Binet<binet@cern.ch>
00006 
00007 // python includes
00008 #include <Python.h>
00009 
00010 // GaudiMP includes
00011 #include "IoComponentMgr.h"
00012 
00013 
00014 // STL includes
00015 
00016 // FrameWork includes
00017 #include "GaudiKernel/SvcFactory.h"
00018 #include "GaudiKernel/Property.h"
00019 
00020 DECLARE_SERVICE_FACTORY(IoComponentMgr)
00021 
00022 
00023 
00024 // Public methods:
00026 
00027 // Constructors
00029 IoComponentMgr::IoComponentMgr( const std::string& name,
00030                                 ISvcLocator* svc )
00031 : base_class(name,svc), m_log(msgSvc(), name ),
00032     m_dict   ( 0 )
00033 {
00034   //
00035   // Property declaration
00036   //
00037   //declareProperty( "Property", m_nProperty );
00038 
00039 //   declareProperty ("Registry",
00040 //                 m_dict_location = "GaudiMP.IoRegistry.registry",
00041 //                 "Location of the python dictionary holding the "
00042 //                 "associations: \n"
00043 //                 " {component-name:{ 'old-fname' : ['io','new-fname'] }}\n"
00044 //                 "\nSyntax: <python-module>.<python-module>.<fct-name> \n"
00045 //                 " where fct-name is a function returning the wanted "
00046 //                 " dictionary.");
00047 }
00048 
00049 // Destructor
00051 IoComponentMgr::~IoComponentMgr()
00052 {
00053   Py_XDECREF (m_dict);
00054 }
00055 
00056 // Service's Hooks
00058 StatusCode IoComponentMgr::initialize()
00059 {
00060   m_log << MSG::INFO << "Initializing " << name() << "..." << endmsg;
00061 
00062   if ( Service::initialize().isFailure() ) {
00063     m_log << MSG::ERROR << "Unable to initialize Service base class" << endmsg;
00064     return StatusCode::FAILURE;
00065   }
00066   m_log.setLevel( m_outputLevel.value() );
00067 
00068   if ( ! Py_IsInitialized() ) {
00069     if (m_log.level() <= MSG::DEBUG) {
00070       m_log << MSG::DEBUG << "Initializing Python" << endmsg;
00071     }
00072     PyEval_InitThreads();
00073     Py_Initialize();
00074 
00075     if ( ! Py_IsInitialized() ) {
00076       m_log << MSG::ERROR << "Unable to initialize Python" << endmsg;
00077       return StatusCode::FAILURE;
00078     }
00079   }
00080 
00081 
00082   // retrieve the python dictionary holding the I/O registry
00083   const std::string py_module_name = "GaudiMP.IoRegistry";
00084   m_log << MSG::DEBUG << "importing module [" << py_module_name << "]..."
00085         << endmsg;
00086   PyObject *module = PyImport_ImportModule ((char*)py_module_name.c_str());
00087   if ( !module || !PyModule_Check (module) ) {
00088     m_log << MSG::ERROR << "Could not import [" << py_module_name << "] !"
00089           << endmsg;
00090     Py_XDECREF (module);
00091     return StatusCode::FAILURE;
00092   }
00093 
00094   const std::string py_class_name = "IoRegistry";
00095   PyObject *pyclass = PyDict_GetItemString (PyModule_GetDict(module),
00096                                             (char*)py_class_name.c_str());
00097   // borrowed ref.
00098   Py_XINCREF (pyclass);
00099   if ( !pyclass ) {
00100     m_log << MSG::ERROR << "Could not import ["
00101           << py_class_name << "] from module ["
00102           << py_module_name << "] !"
00103           << endmsg ;
00104     Py_XDECREF (pyclass);
00105     Py_DECREF  (module);
00106     return StatusCode::FAILURE;
00107   }
00108 
00109   m_dict = PyObject_GetAttrString (pyclass, (char*)"instances");
00110   if ( !m_dict || !PyDict_Check (m_dict) ) {
00111     m_log << MSG::ERROR
00112           << "could not retrieve attribute [instances] from class ["
00113           << py_module_name << "." << py_class_name << "] !" << endmsg;
00114     Py_DECREF (pyclass);
00115     Py_DECREF (module);
00116     return StatusCode::FAILURE;
00117   }
00118 
00119   m_log << MSG::INFO <<  "python I/O registry retrieved [ok]" << endmsg;
00120   if ( m_log.level() <=  MSG::DEBUG ) {
00121     std::string repr = "";
00122     // PyObject_Repr returns a new ref.
00123     PyObject* py_repr = PyObject_Repr (m_dict);
00124     if ( py_repr && PyString_Check(py_repr) ) {
00125       repr = PyString_AsString(py_repr);
00126     }
00127     Py_XDECREF( py_repr );
00128     m_log << MSG::DEBUG << "content: " << repr << endmsg;
00129   }
00130 
00131   return StatusCode::SUCCESS;
00132 }
00133 
00134 StatusCode IoComponentMgr::finalize()
00135 {
00136   m_log << MSG::INFO << "Finalizing " << name() << "..." << endmsg;
00137 
00138 
00139   if (m_log.level() <= MSG::DEBUG) {
00140     m_log << MSG::DEBUG << "Listing all monitored entries: " << std::endl;
00141 
00142     std::string repr = "";
00143     // PyObject_Repr returns a new ref.
00144     PyObject* py_repr = PyObject_Repr (m_dict);
00145     if ( py_repr && PyString_Check(py_repr) ) {
00146       repr = PyString_AsString(py_repr);
00147     }
00148     Py_XDECREF( py_repr );
00149     m_log << MSG::DEBUG << "content: " << repr << endmsg;
00150   }
00151 
00152   return StatusCode::SUCCESS;
00153 }
00154 
00156 // Const methods:
00158 
00161 bool
00162 IoComponentMgr::io_hasitem (IIoComponent* iocomponent) const
00163 {
00164   if ( 0 == iocomponent ) {
00165     return false;
00166   }
00167   const std::string& ioname = iocomponent->name();
00168   IoRegistry_t::const_iterator io = m_ioregistry.find (ioname);
00169   return io != m_ioregistry.end();
00170 }
00171 
00175 bool
00176 IoComponentMgr::io_contains (IIoComponent* iocomponent,
00177                              const std::string& fname) const
00178 {
00179   if ( 0 == iocomponent ) {
00180     return false;
00181   }
00182   const std::string& ioname = iocomponent->name();
00183 
00184   // m_dict is a python dictionary like so:
00185   //  { 'iocomp-name' : { 'oldfname' : [ 'iomode', 'newfname' ] } }
00186 
00187   // -> check there is an 'iocomp-name' entry
00188   // -> retrieve that entry
00189   PyObject *o = PyDict_GetItemString (m_dict, (char*)ioname.c_str());
00190   Py_XINCREF (o);
00191 
00192   // -> check it is a dictionary
00193   if ( NULL==o || !PyDict_Check (o) ) {
00194     Py_XDECREF (o);
00195 
00196     return false;
00197   }
00198 
00199   // -> check 'oldfname' exists
00200   PyObject *item = PyDict_GetItemString (o, (char*)fname.c_str());
00201 
00202   const bool contains = (item != 0);
00203   if ( contains == false ) {
00204     std::string repr = "";
00205     // PyObject_Repr returns a new ref.
00206     PyObject* py_repr = PyObject_Repr (o);
00207     if ( py_repr && PyString_Check(py_repr) ) {
00208       repr = PyString_AsString(py_repr);
00209     }
00210     Py_XDECREF( py_repr );
00211     m_log << MSG::ERROR << "content: " << repr << endmsg;
00212   }
00213   Py_DECREF (o);
00214   Py_XDECREF(item);
00215   return contains;
00216 }
00217 
00219 // Non-const methods:
00221 
00228 StatusCode
00229 IoComponentMgr::io_register (IIoComponent* iocomponent)
00230 {
00231   if ( 0 == iocomponent ) {
00232     m_log << MSG::ERROR
00233           << "io_register (component) received a NULL pointer !" << endmsg;
00234     return StatusCode::FAILURE;
00235   }
00236   const std::string& ioname = iocomponent->name();
00237   IoRegistry_t::iterator itr = m_ioregistry.find (ioname);
00238   if ( itr == m_ioregistry.end() ) {
00239     iocomponent->addRef(); // ownership...
00240     m_ioregistry[ioname] = iocomponent;
00241     m_iostack.push_back (iocomponent);
00242   } else {
00243     m_log << MSG::INFO << "IoComponent[" << iocomponent->name()
00244           <<"] already registered @" << (void*)itr->second << endmsg;
00245   }
00246   return StatusCode::SUCCESS;
00247 }
00248 
00255 StatusCode
00256 IoComponentMgr::io_register (IIoComponent* iocomponent,
00257                              IIoComponentMgr::IoMode::Type iomode,
00258                              const std::string& fname)
00259 {
00260   if ( 0 == iocomponent ) {
00261     return StatusCode::FAILURE;
00262   }
00263   const std::string& ioname = iocomponent->name();
00264 
00265   if ( !io_hasitem (iocomponent) ) {
00266     if ( !io_register (iocomponent).isSuccess() ) {
00267       m_log << MSG::ERROR
00268             << "could not register component [" << iocomponent->name() << "] "
00269             << "with the I/O component manager !"
00270             << endmsg;
00271       return StatusCode::FAILURE;
00272     }
00273   }
00274 
00275   // m_dict is a python dictionary like so:
00276   //  { 'iocomp-name' : { 'oldfname' : [ 'iomode', 'newfname' ] } }
00277 
00278   // -> check there is an 'iocomp-name' entry
00279   // -> retrieve that entry
00280   PyObject *o = PyDict_GetItemString (m_dict, (char*)ioname.c_str());
00281 
00282   // -> check it is a dictionary
00283   if ( NULL==o ) {
00284     o = PyDict_New();
00285     if (NULL == o) {
00286       m_log << MSG::ERROR << "could not create an I/O entry for ["
00287             << ioname << "] "
00288             << "in the I/O registry !" << endmsg;
00289       return StatusCode::FAILURE;
00290     }
00291     if ( 0 != PyDict_SetItemString (m_dict, (char*)ioname.c_str(), o) ) {
00292       Py_DECREF (o);
00293       m_log << MSG::ERROR << "could not create an I/O entry for ["
00294             << ioname << "] " << "in the I/O registry !" << endmsg;
00295       return StatusCode::FAILURE;
00296     }
00297   } else if ( !PyDict_Check (o) ) {
00298     m_log << MSG::ERROR
00299           << "internal consistency error (expected a dictionary !)"
00300           << endmsg;
00301     return StatusCode::FAILURE;
00302   } else {
00303     // borrowed ref.
00304     Py_INCREF (o);
00305   }
00306 
00307   // -> check if 'fname' has already been registered
00308   std::string mode;
00309   switch (iomode) {
00310   case IIoComponentMgr::IoMode::Input: mode ="<input>"; break;
00311   case IIoComponentMgr::IoMode::Output:mode ="<output>";break;
00312   default:
00313     m_log << MSG::ERROR << "unknown value for iomode: [" << iomode << "] !"
00314           << endmsg;
00315     Py_DECREF (o);
00316     return StatusCode::FAILURE;
00317   }
00318 
00319   PyObject *val = PyDict_GetItemString (o, (char*)fname.c_str());
00320   if ( 0 != val ) {
00321     Py_DECREF (o);
00322     return StatusCode::SUCCESS;
00323   }
00324 
00325   val = PyList_New(2);
00326   if ( 0 == val ) {
00327     m_log << MSG::ERROR << "could not allocate a python-list !" << endmsg;
00328     Py_DECREF (o);
00329     return StatusCode::FAILURE;
00330   }
00331 
00332   int err = PyList_SetItem (val,
00333                             0, PyString_FromString ((char*)mode.c_str()));
00334   if (err) {
00335     Py_DECREF (val);
00336     Py_DECREF (o);
00337     m_log << MSG::ERROR << "could not set py-iomode !" << endmsg;
00338     return StatusCode::FAILURE;
00339   }
00340   Py_INCREF (Py_None);
00341   // PyList_SetItem steals the ref...
00342   err = PyList_SetItem (val, 1, Py_None);
00343   if (err) {
00344     Py_DECREF (val);
00345     Py_DECREF (o);
00346     m_log << MSG::ERROR << "could not properly fill python-list !" << endmsg;
00347     return StatusCode::FAILURE;
00348   }
00349   err = PyDict_SetItemString (o, (char*)fname.c_str(), val);
00350   if (err) {
00351     m_log << MSG::ERROR << "could not properly fill registry w/ python-list !"
00352           << endmsg;
00353     Py_DECREF (val);
00354     Py_DECREF (o);
00355     return StatusCode::FAILURE;
00356   }
00357   Py_DECREF (o);
00358   return StatusCode::SUCCESS;
00359 }
00360 
00364 StatusCode
00365 IoComponentMgr::io_retrieve (IIoComponent* iocomponent,
00366                              std::string& fname)
00367 {
00368   if ( 0 == iocomponent ) {
00369     return StatusCode::FAILURE;
00370   }
00371 
00372   const std::string& ioname = iocomponent->name();
00373 
00374   // m_dict is a python dictionary like so:
00375   //  { 'iocomp-name' : { 'oldfname' : [ 'iomode', 'newfname' ] } }
00376 
00377   // -> check there is an 'iocomp-name' entry
00378   // -> retrieve that entry
00379   PyObject *o = PyDict_GetItemString (m_dict, (char*)ioname.c_str());
00380   Py_XINCREF (o);
00381 
00382   // -> check it is a dictionary
00383   if ( NULL==o || !PyDict_Check (o) ) {
00384     Py_XDECREF (o);
00385     return StatusCode::FAILURE;
00386   }
00387 
00388   // -> check 'oldfname' exists
00389   PyObject *pylist = PyDict_GetItemString (o, (char*)fname.c_str());
00390   Py_XINCREF (pylist);
00391 
00392   if ( NULL==pylist || !PyList_Check (pylist) ) {
00393     Py_XDECREF(pylist);
00394     Py_DECREF (o);
00395     return StatusCode::FAILURE;
00396   }
00397 
00398   const std::size_t sz = PyList_Size (pylist);
00399   if ( 2 != sz ) {
00400     m_log << MSG::ERROR << "[" << ioname << "][" << fname << "] list has size ["
00401           << sz << " ! (expected sz==2)"
00402           << endmsg;
00403     Py_DECREF (o);
00404     Py_DECREF (pylist);
00405     return StatusCode::FAILURE;
00406   }
00407 
00408   fname = PyString_AsString ( PyList_GetItem (pylist, 1) );
00409   Py_DECREF (o);
00410   Py_DECREF (pylist);
00411   return StatusCode::SUCCESS;
00412 }
00413 
00418 StatusCode
00419 IoComponentMgr::io_reinitialize ()
00420 {
00421   m_log << MSG::DEBUG << "reinitializing I/O subsystem..." << endmsg;
00422   bool allgood = true;
00423   for ( IoStack_t::iterator io = m_iostack.begin(), ioEnd = m_iostack.end();
00424         io != ioEnd;
00425         ++io ) {
00426     m_log << MSG::DEBUG << " [" << (*io)->name() << "]->io_reinit()..."
00427           << endmsg;
00428     if ( !(*io)->io_reinit().isSuccess() ) {
00429       allgood = false;
00430       m_log << MSG::ERROR << "problem in [" << (*io)->name()
00431             << "]->io_reinit() !" << endmsg;
00432     }
00433     // we are done with this guy... release it
00434     (*io)->release();
00435   }
00436 
00437   // we are done.
00438   // FIXME: shall we allow for multiple io_reinitialize ?
00439   m_iostack.clear();
00440   m_ioregistry.clear();
00441 
00442   return allgood
00443     ? StatusCode::SUCCESS
00444     : StatusCode::FAILURE;
00445 }
00446 
00451 StatusCode
00452 IoComponentMgr::io_finalize ()
00453 {
00454   return StatusCode::SUCCESS;
00455 }
00456 
00458 // Protected methods:
00460 
00462 // Const methods:
00464 
00466 // Non-const methods:
00468 
00469 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:24:46 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004