All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
32 std::ostream&
33 operator<< ( std::ostream& os, const IIoComponentMgr::IoMode::Type& m) {
34  switch (m) {
35  case IIoComponentMgr::IoMode::READ : os << "READ"; break;
36  case IIoComponentMgr::IoMode::WRITE : os << "WRITE"; break;
37  case IIoComponentMgr::IoMode::RW : os << "RW"; break;
38  default:
39  os << "INVALID"; break;
40  }
41 
42  return os;
43 
44 }
45 
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47 
50  DEBMSG << "--> initialize()" << endmsg;
51 
52  if ( Service::initialize().isFailure() ) {
53  error() << "Unable to initialize Service base class" << endmsg;
54  return StatusCode::FAILURE;
55  }
56 
57  IIncidentSvc* p_incSvc(0);
58 
59  if (service("IncidentSvc", p_incSvc, true).isFailure()) {
60  error() << "unable to get the IncidentSvc" << endmsg;
61  return StatusCode::FAILURE;
62  } else {
63  p_incSvc->addListener( this, IncidentType::BeginOutputFile, 100, true);
64  p_incSvc->addListener( this, IncidentType::BeginInputFile, 100, true);
65  }
66 
67  return StatusCode::SUCCESS;
68 }
69 
70 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
71 
74  DEBMSG << "--> finalize()" << endmsg;
75 
76  return StatusCode::SUCCESS;
77 }
78 
79 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
80 
83 bool
85  DEBMSG << "--> io_hasitem()" << endmsg;
86  if ( 0 == iocomponent ) {
87  return false;
88  }
89  const std::string& ioname = iocomponent->name();
90  IoRegistry_t::const_iterator io = m_ioregistry.find (ioname);
91  return io != m_ioregistry.end();
92 }
93 
94 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
95 
99 bool
101  const std::string& fname) const
102 {
103  DEBMSG << "--> io_contains()" << endmsg;
104  if ( 0 == iocomponent ) {
105  return false;
106  }
107  const std::string& ioname = iocomponent->name();
108 
109  DEBMSG << "io_contains: c: " << ioname << " f: " << fname << endmsg;
110 
111  pair<iodITR,iodITR> fit = m_cdict.equal_range(iocomponent);
112  if (fit.first == fit.second) {
113  return false;
114  } else {
115  iodITR it;
116  for (it=fit.first; it != fit.second; ++it) {
117  IoComponentEntry ioe = it->second;
118  DEBMSG << " " << ioe << endmsg;
119  if (ioe.m_oldfname == "") {
120  error() << "IIoComponent " << ioname
121  << " has empty old filename" << endmsg;
122  return false;
123  } else if (ioe.m_oldfname == fname) {
124  return true;
125  }
126  }
127  }
128 
129  return false;
130 }
131 
132 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
133 
142 {
143  if ( !iocomponent ) {
144  error()
145  << "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()
158  <<"] already registered @" << (void*)itr->second << endmsg;
159  }
160  return StatusCode::SUCCESS;
161 }
162 
163 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
164 
174  const std::string& fname,
175  const std::string& pfn)
176 {
177  if ( 0 == iocomponent ) {
178  return StatusCode::FAILURE;
179  }
180  const std::string& ioname = iocomponent->name();
181 
182  DEBMSG << "--> io_register(" << ioname << ","
183  << ( (iomode== IIoComponentMgr::IoMode::READ) ? "R" : "W" )
184  << "," << fname << ")" << endmsg;
185 
186  if ( !io_hasitem (iocomponent) ) {
187  if ( !io_register (iocomponent).isSuccess() ) {
188  error()
189  << "could not register component [" << iocomponent->name() << "] "
190  << "with the I/O component manager !"
191  << endmsg;
192  return StatusCode::FAILURE;
193  }
194  }
195 
196  pair<iodITR,iodITR> fit = m_cdict.equal_range(iocomponent);
197  if (fit.first != fit.second) {
198  for (iodITR it=fit.first; it != fit.second; ++it) {
199  IoComponentEntry ioe = it->second;
200  if (ioe.m_oldfname == fname) {
201  if (ioe.m_iomode == iomode) {
202  info() << "IoComponent " << ioname
203  << " has already had file " << fname
204  << " registered with i/o mode " << iomode << endmsg;
205  return StatusCode::SUCCESS;
206  } else {
207  warning() << "IoComponent " << ioname
208  << " has already had file " << fname
209  << " registered with a different i/o mode " << ioe.m_iomode
210  << " - now trying " << iomode << endmsg;
211  }
212  }
213  }
214  }
215 
216  // We need to take into account that boost::filesystem::absolute() does not
217  // work for files read from eos, i.e. starting with "root:"
218  std::string tmp_name = pfn.empty()?fname:pfn;
219  bool from_eos = tmp_name.find("root:")==0;
220  IoComponentEntry ioc(fname,(from_eos?tmp_name:boost::filesystem::absolute(tmp_name).string()),iomode);
222 
223  return StatusCode::SUCCESS;
224 }
225 
226 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
227 
233  std::string& fname)
234 {
235  if ( 0 == iocomponent ) {
236  return StatusCode::FAILURE;
237  }
238 
239  std::string ofname = fname;
240  const std::string& ioname = iocomponent->name();
241 
242  DEBMSG << "--> io_retrieve(" << ioname << "," << fname << ")"
243  << endmsg;
244 
245  iodITR it;
246  if (!findComp(iocomponent,ofname,it)) {
247  DEBMSG << "could not find c: " << ioname << " old_f: " << ofname << endmsg;
248  return StatusCode::FAILURE;
249  } else {
250 
251  IoDict_t::iterator it;
252  for (it = m_cdict.equal_range(iocomponent).first;
253  it != m_cdict.equal_range(iocomponent).second;
254  ++it) {
255 
256  if (it->second.m_oldfname == ofname) {
257  DEBMSG << "retrieving new name for the component " << iocomponent->name()
258  << " old name: " << ofname
259  << ", new name: " << it->second.m_newfname << endmsg;
260  fname = it->second.m_newfname;
261  return StatusCode::SUCCESS;
262  }
263  }
264  }
265 
266  DEBMSG << "Unexpected error! Unable to find entry in the dictionary corresponding to old filename: " << ofname << endmsg;
267  return StatusCode::FAILURE;
268 }
269 
270 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
271 
278 {
279  ON_DEBUG {
280  debug() << "--> io_reinitialize()" << endmsg;
281  debug() << "reinitializing I/O subsystem..." << endmsg;
282  debug() << "Listing all monitored entries: " << std::endl;
283  debug() << list() << endmsg;
284  }
285 
286  bool allgood = true;
287  for ( auto& io : m_iostack ) {
288  DEBMSG << " [" << io->name() << "]->io_reinit()..." << endmsg;
289  if ( !io->io_reinit().isSuccess() ) {
290  allgood = false;
291  error() << "problem in [" << io->name()
292  << "]->io_reinit() !" << endmsg;
293  }
294  // we are done with this guy... release it
295  io->release();
296  }
297 
298  // we are done.
299  // FIXME: shall we allow for multiple io_reinitialize ?
300  // m_iostack.clear();
301  // m_ioregistry.clear();
302  // m_cdict.clear();
303 
304  return allgood
307 }
308 
309 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
310 
313  const std::string& new_fname) {
314 
315  DEBMSG << "--> io_update(" << ioc->name() << ","
316  << old_fname << "," << new_fname << ")" << endmsg;
317 
318  IoDict_t::iterator it;
319  for (it = m_cdict.equal_range(ioc).first;
320  it != m_cdict.equal_range(ioc).second;
321  ++it) {
322 
323  if (it->second.m_oldfname == old_fname) {
324  DEBMSG << "updating " << ioc->name() << " f: " << old_fname << " -> "
325  << new_fname << endmsg;
326  it->second.m_newfname = new_fname;
327  return StatusCode::SUCCESS;
328  }
329  }
330 
331  return StatusCode::FAILURE;
332 
333 }
334 
335 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
336 
339 
340  DEBMSG << "--> io_update(" << ioc->name() << ","
341  << work_dir << ")" << endmsg;
342 
343  IoDict_t::iterator it;
344  for (it = m_cdict.equal_range(ioc).first;
345  it != m_cdict.equal_range(ioc).second;
346  ++it) {
347 
348  switch(it->second.m_iomode) {
350  {
351  it->second.m_newfname = it->second.m_oldabspath;
352  break;
353  }
355  {
356  boost::filesystem::path oldPath(it->second.m_oldfname);
357  if(oldPath.is_relative() &&
358  oldPath.filename()==oldPath.relative_path()) {
359 
360  // Only file name was provided for writing. This is the usual mode of operation
361  // ***
362  // NB. In such cases it would make sense to set newfname=oldfname, however this will break
363  // existing client codes, which assume that newfname contains "/"
364  // Thus we set newfname=workdir/oldfname
365  // ***
366 
367  boost::filesystem::path newfname(work_dir);
368  newfname /= oldPath;
369  it->second.m_newfname = newfname.string();
370  }
371  else {
372  // New name should be the old absolute path
373  it->second.m_newfname = it->second.m_oldabspath;
374  }
375 
376  break;
377  }
378  default:
379  {
380  // Don't know how to deal with either RW or INVALID
381  error() << "Unable to update IoComponent for the mode " << it->second.m_iomode << endmsg;
382  return StatusCode::FAILURE;
383  }
384  }
385 
386  } // for
387 
388  return StatusCode::SUCCESS;
389 
390 }
391 
392 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
393 
396 {
397  DEBMSG << "-->io_update_all for the directory " << work_dir << endmsg;
398  bool allgood = true;
399  for ( IoStack_t::iterator io = m_iostack.begin(), ioEnd = m_iostack.end();
400  io != ioEnd;
401  ++io ) {
402  if ( !io_update(*io,work_dir).isSuccess() ) {
403  allgood = false;
404  error() << "problem in [" << (*io)->name()
405  << "]->io_update() !" << endmsg;
406  }
407  }
408  return allgood ? StatusCode::SUCCESS : StatusCode::FAILURE;
409 }
410 
411 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
412 
419 {
420  ON_DEBUG {
421  debug() << "--> io_finalize()" << endmsg;
422  debug() << "finalizing I/O subsystem..." << endmsg;
423  debug() << "Listing all monitored entries: " << std::endl;
424  debug() << list() << endmsg;
425  }
426 
427  bool allgood = true;
428  for ( IoStack_t::iterator io = m_iostack.begin(), ioEnd = m_iostack.end();
429  io != ioEnd;
430  ++io ) {
431  DEBMSG << " [" << (*io)->name() << "]->io_finalize()..."
432  << endmsg;
433  if ( !(*io)->io_finalize().isSuccess() ) {
434  allgood = false;
435  error() << "problem in [" << (*io)->name()
436  << "]->io_finalize() !" << endmsg;
437  }
438  }
439 
440  return allgood
443 }
444 
445 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
446 
447 bool
449  const {
450 
452  if (!findComp(c,pit)) {
453  itr = pit.first;
454  return false;
455  }
456  return std::any_of( pit.first, pit.second,
457  [&](IoDict_t::const_reference i)
458  { return i.second.m_oldfname == f; } );
459 
460 }
461 
462 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
463 
464 bool
466 
467  pit = m_cdict.equal_range(c);
468  return pit.first != pit.second;
469 
470 }
471 
472 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
473 
474 bool
476  std::pair<iodITR,iodITR>& pit) const {
477 
478  pit.first = m_cdict.end();
479  pit.second = m_cdict.end();
480 
481  auto itr = m_ioregistry.find(c);
482  return ( itr != m_ioregistry.end() ) && findComp(itr->second, pit);
483 }
484 
485 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
486 
489 
490  ostringstream ost;
491 
492  ost << "Listing all IoComponents (" << m_cdict.size() << "): " << endl;
493  for (const auto& i : m_cdict ) {
494  ost << " " << i.first->name() << " " << i.second << endl;
495  }
496 
497  return ost.str();
498 }
499 
500 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
501 
502 void
504 
506 
507 
508  if ( i.type() == IncidentType::BeginInputFile ) {
509 
510  const FileIncident *fi = dynamic_cast<const FileIncident*> ( &i );
511  DEBMSG << "BeginInputFile: s: " << fi->source() << " t: " << fi->type()
512  << " n: " << fi->fileName() << " g: " << fi->fileGuid()
513  << endmsg;
514 
515  if (findComp(fi->source(),pit)) {
516  DEBMSG << " found component: " << endmsg;
517  while (pit.first != pit.second) {
518  IIoComponent* c = pit.first->first;
519  IoComponentEntry e = pit.first->second;
520  DEBMSG << " c: " << c->name() << " " << e << endmsg;
521 
522  ++pit.first;
523  }
524  } else {
525  DEBMSG << " could not find component \"" << fi->source()
526  << "\"!" << endmsg;
527  }
528 
529 
530 
531  } else if ( i.type() == IncidentType::BeginOutputFile ) {
532 
533  const FileIncident *fi = dynamic_cast<const FileIncident*> ( &i );
534  DEBMSG << "BeginOutputFile: s: " << fi->source() << " t: " << fi->type()
535  << " n: " << fi->fileName() << " g: " << fi->fileGuid()
536  << endmsg;
537 
538  if (findComp(fi->source(),pit)) {
539  DEBMSG << " found component: " << endmsg;
540  while (pit.first != pit.second) {
541  IIoComponent* c = pit.first->first;
542  IoComponentEntry e = pit.first->second;
543  DEBMSG << " c: " << c->name() << " " << e << endmsg;
544 
545  ++pit.first;
546  }
547  } else {
548  DEBMSG << " could not find component \"" << fi->source()
549  << "\"!" << endmsg;
550  }
551 
552  }
553 
554 }
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:74
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:36
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:26
constexpr double m
Definition: SystemOfUnits.h:93
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:65
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:64
Type
the list of available types for ntuples
Definition: TupleObj.h:79
STL class.
T equal_range(T...args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
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