The Gaudi Framework  v29r0 (ff2e7097)
IoComponentMgr.cpp
Go to the documentation of this file.
1 // IoComponentMgr.cxx
3 // Implementation file for class IoComponentMgr
4 // Author: S.Binet<binet@cern.ch>
6 
7 // GaudiMP includes
8 #include "IoComponentMgr.h"
11 
12 #include "GaudiKernel/IFileMgr.h"
14 #include <boost/filesystem.hpp>
15 
16 // STL includes
17 
18 // FrameWork includes
19 #include "GaudiKernel/Property.h"
20 
21 #define ON_DEBUG if ( UNLIKELY( outputLevel() <= MSG::DEBUG ) )
22 #define ON_VERBOSE if ( UNLIKELY( outputLevel() <= MSG::VERBOSE ) )
23 
24 #define DEBMSG ON_DEBUG debug()
25 #define VERMSG ON_VERBOSE verbose()
26 
28 
29 using namespace std;
30 
31 std::ostream& operator<<( std::ostream& os, const IIoComponentMgr::IoMode::Type& m )
32 {
33  switch ( m ) {
35  os << "READ";
36  break;
38  os << "WRITE";
39  break;
41  os << "RW";
42  break;
43  default:
44  os << "INVALID";
45  break;
46  }
47 
48  return os;
49 }
50 
51 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
52 
54 {
55  DEBMSG << "--> initialize()" << endmsg;
56 
57  if ( Service::initialize().isFailure() ) {
58  error() << "Unable to initialize Service base class" << endmsg;
59  return StatusCode::FAILURE;
60  }
61 
62  IIncidentSvc* p_incSvc( 0 );
63 
64  if ( service( "IncidentSvc", p_incSvc, true ).isFailure() ) {
65  error() << "unable to get the IncidentSvc" << endmsg;
66  return StatusCode::FAILURE;
67  } else {
68  p_incSvc->addListener( this, IncidentType::BeginOutputFile, 100, true );
69  p_incSvc->addListener( this, IncidentType::BeginInputFile, 100, true );
70  }
71 
72  return StatusCode::SUCCESS;
73 }
74 
75 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
76 
78 {
79  DEBMSG << "--> finalize()" << endmsg;
80 
81  return StatusCode::SUCCESS;
82 }
83 
84 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
85 
88 bool IoComponentMgr::io_hasitem( IIoComponent* iocomponent ) const
89 {
90  DEBMSG << "--> io_hasitem()" << endmsg;
91  if ( 0 == iocomponent ) {
92  return false;
93  }
94  const std::string& ioname = iocomponent->name();
95  IoRegistry_t::const_iterator io = m_ioregistry.find( ioname );
96  return io != m_ioregistry.end();
97 }
98 
99 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
100 
104 bool IoComponentMgr::io_contains( IIoComponent* iocomponent, const std::string& fname ) const
105 {
106  DEBMSG << "--> io_contains()" << endmsg;
107  if ( 0 == iocomponent ) {
108  return false;
109  }
110  const std::string& ioname = iocomponent->name();
111 
112  DEBMSG << "io_contains: c: " << ioname << " f: " << fname << endmsg;
113 
114  pair<iodITR, iodITR> fit = m_cdict.equal_range( iocomponent );
115  if ( fit.first == fit.second ) {
116  return false;
117  } else {
118  iodITR it;
119  for ( it = fit.first; it != fit.second; ++it ) {
120  IoComponentEntry ioe = it->second;
121  DEBMSG << " " << ioe << endmsg;
122  if ( ioe.m_oldfname == "" ) {
123  error() << "IIoComponent " << ioname << " has empty old filename" << endmsg;
124  return false;
125  } else if ( ioe.m_oldfname == fname ) {
126  return true;
127  }
128  }
129  }
130 
131  return false;
132 }
133 
134 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
135 
143 {
144  if ( !iocomponent ) {
145  error() << "io_register (component) received a NULL pointer !" << endmsg;
146  return StatusCode::FAILURE;
147  }
148  const std::string& ioname = iocomponent->name();
149  DEBMSG << "--> io_register(" << ioname << ")" << endmsg;
150  auto itr = m_ioregistry.find( ioname );
151  if ( itr == m_ioregistry.end() ) {
152  DEBMSG << " registering IoComponent \"" << ioname << "\"" << endmsg;
153  iocomponent->addRef(); // ownership...
154  m_ioregistry[ioname] = iocomponent;
155  m_iostack.push_back( iocomponent );
156  } else {
157  info() << "IoComponent[" << iocomponent->name() << "] already registered @" << (void*)itr->second << endmsg;
158  }
159  return StatusCode::SUCCESS;
160 }
161 
162 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
163 
171  const std::string& fname, const std::string& pfn )
172 {
173  if ( 0 == iocomponent ) {
174  return StatusCode::FAILURE;
175  }
176  const std::string& ioname = iocomponent->name();
177 
178  DEBMSG << "--> io_register(" << ioname << "," << ( ( iomode == IIoComponentMgr::IoMode::READ ) ? "R" : "W" ) << ","
179  << fname << ")" << endmsg;
180 
181  if ( !io_hasitem( iocomponent ) ) {
182  if ( !io_register( iocomponent ).isSuccess() ) {
183  error() << "could not register component [" << iocomponent->name() << "] "
184  << "with the I/O component manager !" << endmsg;
185  return StatusCode::FAILURE;
186  }
187  }
188 
189  pair<iodITR, iodITR> fit = m_cdict.equal_range( iocomponent );
190  if ( fit.first != fit.second ) {
191  for ( iodITR it = fit.first; it != fit.second; ++it ) {
192  IoComponentEntry ioe = it->second;
193  if ( ioe.m_oldfname == fname ) {
194  if ( ioe.m_iomode == iomode ) {
195  info() << "IoComponent " << ioname << " has already had file " << fname << " registered with i/o mode "
196  << iomode << endmsg;
197  return StatusCode::SUCCESS;
198  } else {
199  warning() << "IoComponent " << ioname << " has already had file " << fname
200  << " registered with a different i/o mode " << ioe.m_iomode << " - now trying " << iomode << endmsg;
201  }
202  }
203  }
204  }
205 
206  // We need to take into account that boost::filesystem::absolute() does not
207  // work for files read from eos, i.e. starting with "root:"
208  std::string tmp_name = pfn.empty() ? fname : pfn;
209  bool from_eos = tmp_name.find( "root:" ) == 0;
210  IoComponentEntry ioc( fname, ( from_eos ? tmp_name : boost::filesystem::absolute( tmp_name ).string() ), iomode );
212 
213  return StatusCode::SUCCESS;
214 }
215 
216 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
217 
222 {
223  if ( 0 == iocomponent ) {
224  return StatusCode::FAILURE;
225  }
226 
227  std::string ofname = fname;
228  const std::string& ioname = iocomponent->name();
229 
230  DEBMSG << "--> io_retrieve(" << ioname << "," << fname << ")" << endmsg;
231 
232  iodITR it;
233  if ( !findComp( iocomponent, ofname, it ) ) {
234  DEBMSG << "could not find c: " << ioname << " old_f: " << ofname << endmsg;
235  return StatusCode::FAILURE;
236  } else {
237 
238  IoDict_t::iterator it;
239  for ( it = m_cdict.equal_range( iocomponent ).first; it != m_cdict.equal_range( iocomponent ).second; ++it ) {
240 
241  if ( it->second.m_oldfname == ofname ) {
242  DEBMSG << "retrieving new name for the component " << iocomponent->name() << " old name: " << ofname
243  << ", new name: " << it->second.m_newfname << endmsg;
244  fname = it->second.m_newfname;
245  return StatusCode::SUCCESS;
246  }
247  }
248  }
249 
250  DEBMSG << "Unexpected error! Unable to find entry in the dictionary corresponding to old filename: " << ofname
251  << endmsg;
252  return StatusCode::FAILURE;
253 }
254 
255 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
256 
262 {
263  ON_DEBUG
264  {
265  debug() << "--> io_reinitialize()" << endmsg;
266  debug() << "reinitializing I/O subsystem..." << endmsg;
267  debug() << "Listing all monitored entries: " << std::endl;
268  debug() << list() << endmsg;
269  }
270 
271  bool allgood = true;
272  for ( auto& io : m_iostack ) {
273  DEBMSG << " [" << io->name() << "]->io_reinit()..." << endmsg;
274  if ( !io->io_reinit().isSuccess() ) {
275  allgood = false;
276  error() << "problem in [" << io->name() << "]->io_reinit() !" << endmsg;
277  }
278  // we are done with this guy... release it
279  io->release();
280  }
281 
282  // we are done.
283  // FIXME: shall we allow for multiple io_reinitialize ?
284  // m_iostack.clear();
285  // m_ioregistry.clear();
286  // m_cdict.clear();
287 
288  return allgood ? StatusCode::SUCCESS : StatusCode::FAILURE;
289 }
290 
291 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
292 
293 StatusCode IoComponentMgr::io_update( IIoComponent* ioc, const std::string& old_fname, const std::string& new_fname )
294 {
295 
296  DEBMSG << "--> io_update(" << ioc->name() << "," << old_fname << "," << new_fname << ")" << endmsg;
297 
298  IoDict_t::iterator it;
299  for ( it = m_cdict.equal_range( ioc ).first; it != m_cdict.equal_range( ioc ).second; ++it ) {
300 
301  if ( it->second.m_oldfname == old_fname ) {
302  DEBMSG << "updating " << ioc->name() << " f: " << old_fname << " -> " << new_fname << endmsg;
303  it->second.m_newfname = new_fname;
304  return StatusCode::SUCCESS;
305  }
306  }
307 
308  return StatusCode::FAILURE;
309 }
310 
311 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
312 
314 {
315 
316  DEBMSG << "--> io_update(" << ioc->name() << "," << work_dir << ")" << endmsg;
317 
318  IoDict_t::iterator it;
319  for ( it = m_cdict.equal_range( ioc ).first; it != m_cdict.equal_range( ioc ).second; ++it ) {
320 
321  switch ( it->second.m_iomode ) {
323  it->second.m_newfname = it->second.m_oldabspath;
324  break;
325  }
327  boost::filesystem::path oldPath( it->second.m_oldfname );
328  if ( oldPath.is_relative() && oldPath.filename() == oldPath.relative_path() ) {
329 
330  // Only file name was provided for writing. This is the usual mode of operation
331  // ***
332  // NB. In such cases it would make sense to set newfname=oldfname, however this will break
333  // existing client codes, which assume that newfname contains "/"
334  // Thus we set newfname=workdir/oldfname
335  // ***
336 
337  boost::filesystem::path newfname( work_dir );
338  newfname /= oldPath;
339  it->second.m_newfname = newfname.string();
340  } else {
341  // New name should be the old absolute path
342  it->second.m_newfname = it->second.m_oldabspath;
343  }
344 
345  break;
346  }
347  default: {
348  // Don't know how to deal with either RW or INVALID
349  error() << "Unable to update IoComponent for the mode " << it->second.m_iomode << endmsg;
350  return StatusCode::FAILURE;
351  }
352  }
353 
354  } // for
355 
356  return StatusCode::SUCCESS;
357 }
358 
359 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
360 
362 {
363  DEBMSG << "-->io_update_all for the directory " << work_dir << endmsg;
364  bool allgood = true;
365  for ( IoStack_t::iterator io = m_iostack.begin(), ioEnd = m_iostack.end(); io != ioEnd; ++io ) {
366  if ( !io_update( *io, work_dir ).isSuccess() ) {
367  allgood = false;
368  error() << "problem in [" << ( *io )->name() << "]->io_update() !" << endmsg;
369  }
370  }
371  return allgood ? StatusCode::SUCCESS : StatusCode::FAILURE;
372 }
373 
374 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
375 
381 {
382  ON_DEBUG
383  {
384  debug() << "--> io_finalize()" << endmsg;
385  debug() << "finalizing I/O subsystem..." << endmsg;
386  debug() << "Listing all monitored entries: " << std::endl;
387  debug() << list() << endmsg;
388  }
389 
390  bool allgood = true;
391  for ( IoStack_t::iterator io = m_iostack.begin(), ioEnd = m_iostack.end(); io != ioEnd; ++io ) {
392  DEBMSG << " [" << ( *io )->name() << "]->io_finalize()..." << endmsg;
393  if ( !( *io )->io_finalize().isSuccess() ) {
394  allgood = false;
395  error() << "problem in [" << ( *io )->name() << "]->io_finalize() !" << endmsg;
396  }
397  }
398 
399  return allgood ? StatusCode::SUCCESS : StatusCode::FAILURE;
400 }
401 
402 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
403 
405 {
406 
408  if ( !findComp( c, pit ) ) {
409  itr = pit.first;
410  return false;
411  }
412  return std::any_of( pit.first, pit.second, [&]( IoDict_t::const_reference i ) { return i.second.m_oldfname == f; } );
413 }
414 
415 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
416 
418 {
419 
420  pit = m_cdict.equal_range( c );
421  return pit.first != pit.second;
422 }
423 
424 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
425 
427 {
428 
429  pit.first = m_cdict.end();
430  pit.second = m_cdict.end();
431 
432  auto itr = m_ioregistry.find( c );
433  return ( itr != m_ioregistry.end() ) && findComp( itr->second, pit );
434 }
435 
436 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
437 
439 {
440 
441  ostringstream ost;
442 
443  ost << "Listing all IoComponents (" << m_cdict.size() << "): " << endl;
444  for ( const auto& i : m_cdict ) {
445  ost << " " << i.first->name() << " " << i.second << endl;
446  }
447 
448  return ost.str();
449 }
450 
451 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
452 
454 {
455 
457 
458  if ( i.type() == IncidentType::BeginInputFile ) {
459 
460  const FileIncident* fi = dynamic_cast<const FileIncident*>( &i );
461  DEBMSG << "BeginInputFile: s: " << fi->source() << " t: " << fi->type() << " n: " << fi->fileName()
462  << " g: " << fi->fileGuid() << endmsg;
463 
464  if ( findComp( fi->source(), pit ) ) {
465  DEBMSG << " found component: " << endmsg;
466  while ( pit.first != pit.second ) {
467  IIoComponent* c = pit.first->first;
468  IoComponentEntry e = pit.first->second;
469  DEBMSG << " c: " << c->name() << " " << e << endmsg;
470 
471  ++pit.first;
472  }
473  } else {
474  DEBMSG << " could not find component \"" << fi->source() << "\"!" << endmsg;
475  }
476 
477  } else if ( i.type() == IncidentType::BeginOutputFile ) {
478 
479  const FileIncident* fi = dynamic_cast<const FileIncident*>( &i );
480  DEBMSG << "BeginOutputFile: s: " << fi->source() << " t: " << fi->type() << " n: " << fi->fileName()
481  << " g: " << fi->fileGuid() << endmsg;
482 
483  if ( findComp( fi->source(), pit ) ) {
484  DEBMSG << " found component: " << endmsg;
485  while ( pit.first != pit.second ) {
486  IIoComponent* c = pit.first->first;
487  IoComponentEntry e = pit.first->second;
488  DEBMSG << " c: " << c->name() << " " << e << endmsg;
489 
490  ++pit.first;
491  }
492  } else {
493  DEBMSG << " could not find component \"" << fi->source() << "\"!" << endmsg;
494  }
495  }
496 }
StatusCode finalize() override
StatusCode initialize() override
Definition: Service.cpp:64
This class is the FileIncident.
Definition: FileIncident.h:17
T empty(T...args)
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
bool io_contains(IIoComponent *iocomponent, const std::string &fname) const override
: check if the registry contains a given IIoComponent and that component had
This file contains the class definition for the FileIncident class.
const std::string & source() const
Access to the source of the incident.
Definition: Incident.h:47
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
T endl(T...args)
IoDict_t::const_iterator iodITR
STL namespace.
IoRegistry_t m_ioregistry
Registry of IIoComponents.
T end(T...args)
void handle(const Incident &) override
#define DEBMSG
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:33
STL class.
std::string list() const
StatusCode initialize() override
Gaudi Service Implementation.
T push_back(T...args)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
bool findComp(IIoComponent *, const std::string &, iodITR &) const
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
constexpr double m
Definition: SystemOfUnits.h:94
StatusCode io_register(IIoComponent *iocomponent) override
: allow a IIoComponent to register itself with this manager so appropriate actions can be taken when ...
StatusCode io_update(IIoComponent *iocomponent, const std::string &old_fname, const std::string &new_fname) override
: allow a IIoComponent to update the contents of the registry with a new file name ...
#define ON_DEBUG
std::string m_oldfname
T insert(T...args)
T find(T...args)
T size(T...args)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
IIoComponentMgr::IoMode::Type m_iomode
T begin(T...args)
StatusCode io_update_all(const std::string &work_dir) override
: Update all IIoComponents with a new work directory
T any_of(T...args)
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
const std::string & fileGuid() const
Definition: FileIncident.h:62
StatusCode io_retrieve(IIoComponent *iocomponent, std::string &fname) override
: retrieve the new filename for a given IIoComponent and
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Service.h:85
StatusCode io_finalize() override
: finalize the I/O subsystem.
StatusCode io_reinitialize() override
: reinitialize the I/O subsystem.
IoStack_t m_iostack
Stack of IIoComponents to properly handle order of registration.
const std::string & fileName() const
Definition: FileIncident.h:61
Type
the list of available types for ntuples
Definition: TupleObj.h:84
STL class.
T equal_range(T...args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
virtual const std::string & name() const =0
Retrieve the name of the instance.
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:23
bool io_hasitem(IIoComponent *iocomponent) const override
: check if the registry contains a given IIoComponent