ATLAS Offline Software
CloneService.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
8 #include <cassert>
9 #include <vector>
10 
11 #include "GaudiKernel/ISvcLocator.h"
12 #include "GaudiKernel/ISvcManager.h"
13 #include "GaudiKernel/MsgStream.h"
14 #include "GaudiKernel/Service.h"
15 #include "GaudiKernel/SmartIF.h"
16 #include "GaudiKernel/System.h"
17 
18 
19 namespace CloneService {
21  StatusCode clone(const IService* iParent, const std::string& childName,
22  Service*& child)
23  {
24  //check the parent pointer is valid
25  const Service* parent = dynamic_cast<const Service*>(iParent);
26  if ( !parent ) {
27  throw GaudiException("parent " + iParent->name() + " is not a service!",
28  "CloneService", StatusCode::FAILURE);
29  return StatusCode::FAILURE;
30  }
31 
32  MsgStream mlog( parent->msgSvc(), "CloneService" );
33  ISvcLocator* svcLoc = parent->serviceLocator();
34 
35  //Create the child unless it is already there. We cannot use the createIf`
36  //feature of ISvcLocator because that tries to initialize the service immediately.
37  if ( svcLoc->existsService(childName) ) {
38  mlog << MSG::DEBUG
39  << "Found service " << childName
40  << endmsg;
41  } else {
42  // can we access the Service Manager interface?
43  SmartIF<ISvcManager> svcMgr(svcLoc);
44  CHECK_WITH_CONTEXT( svcMgr.isValid(), "CloneService" );
45 
46  // Create the service
47  const std::string& parentType = System::typeinfoName(typeid(*parent));
48  Gaudi::Utils::TypeNameString tn(childName, parentType);
49 
50  child = dynamic_cast<Service*>(svcMgr->createService(tn).get());
51  if ( child ) {
52  mlog << MSG::DEBUG
53  << "Created service " << childName << " of type " << parentType
54  << endmsg;
55  } else {
56  mlog << MSG::ERROR
57  << "Failed to create " << childName << " of type " << parentType
58  << endmsg;
59  return StatusCode::FAILURE;
60  }
61  }
62 
63  //now copy parent's properties into child
64  for (Gaudi::Details::PropertyBase* prop : parent->getProperties()) {
65  if ( child->setProperty(*prop).isFailure() ) {
66  mlog << MSG::ERROR
67  << "Failed to set child property " << prop->name() << endmsg;
68  return StatusCode::FAILURE;
69  }
70  }
71 
72  //finally put the service in the same state as the parent
73  //FIXME should we handle the case in which the parent is RUNNING?
74  if (Gaudi::StateMachine::INITIALIZED == parent->FSMState() &&
75  Gaudi::StateMachine::CONFIGURED == child->FSMState())
76  return child->sysInitialize();
77  else {
78  mlog << MSG::DEBUG
79  << "Did not initialize " << childName
80  << endmsg;
81  return StatusCode::SUCCESS;
82  }
83  }
84 }
CHECK_WITH_CONTEXT
#define CHECK_WITH_CONTEXT(...)
Evaluate an expression and check for errors, with an explicitly specified context name.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:396
StdJOSetup.svcMgr
svcMgr
Definition: StdJOSetup.py:33
CloneService
Definition: CloneService.h:11
python.InDetPriVxFinderConfig.mlog
mlog
Definition: InDetPriVxFinderConfig.py:134
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CloneService.h
errorcheck.h
Helpers for checking error return status codes and reporting errors.
CloneService::clone
StatusCode clone(const IService *parent, const std::string &childName, Service *&child)
given a reference to a parent svc sets a reference to a cloned child
Definition: CloneService.cxx:21
DEBUG
#define DEBUG
Definition: page_access.h:11