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