ATLAS Offline Software
AthenaRootStreamerSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
11 #include "AthenaRootStreamerSvc.h"
12 #include "AthenaRootStreamer.h"
15 
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/IService.h"
18 
19 #include "StorageSvc/DbSession.h"
20 
21 #include "DataModelRoot/RootType.h"
22 #include "TInterpreter.h"
23 
24 #include <mutex>
25 #include <vector>
26 
27 
28 AthenaRootStreamerSvc::AthenaRootStreamerSvc(const std::string& name, ISvcLocator* pSvcLocator)
29  : AthService(name, pSvcLocator),
30  m_streamerMap()
31 {
32  declareProperty( "Streamers", m_streamerClassNames );
33 }
34 
35 
37 {
38 }
39 
40 
42 {
44 
45  pool::DbSession session;
46  // initialize the session
47  // using NULL context, hopefully not a problem
48  pool::DbStatus rc = session.open();
49  // create ROOT-type database object -
50  // this loads the ROOT storage service plugin and
51  // initializes POOL/ROOT class loader needed by GetClass()
52  if( rc != pool::DbStatus::Success || ! session.db(pool::ROOT_StorageType) ) {
53  ATH_MSG_ERROR ( "Failed to open POOL/ROOT session" );
54  return StatusCode::FAILURE;
55  }
56  ATH_MSG_INFO ( "POOL/ROOT class loader initialized" );
57  session.close();
58 
59  StatusCode status = StatusCode::SUCCESS;
60  if( m_streamerClassNames.value().size() ) {
61  ATH_MSG_INFO ( m_streamerClassNames.value().size() << " ROOT streamers declared" );
62 
63  std::vector< std::string >::const_iterator i = m_streamerClassNames.value().begin();
64  while( i != m_streamerClassNames.value().end() ) {
65  ATH_MSG_INFO ( " - Streamer name:" << *i );
66  if( AddStreamer( *i++ ).isFailure() )
67  status = StatusCode::FAILURE;
68  }
69  }
70 
71  return status;
72 }
73 
74 
76 {
77  // Destroy converter Objects created by the service
78  for (auto& p : m_createdConverters)
79  {
80  p.first.Destruct (p.second);
81  }
82  m_createdConverters.clear();
83 
84  // do NOT delete the streamers created by the service - they are owned by TClass
85  m_streamerMap.clear();
86 
87  return AthService::finalize();
88 }
89 
90 
91 StatusCode AthenaRootStreamerSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)
92 {
93  if ( IAthenaRootStreamerSvc::interfaceID().versionMatch(riid) ) {
94  *ppvInterface = dynamic_cast<AthenaRootStreamerSvc*>(this);
95  } else {
96  // Interface is not directly available: try out a base class
97  return(AthService::queryInterface(riid, ppvInterface));
98  }
99  addRef();
100  return(StatusCode::SUCCESS);
101 }
102 
103 
104 const InterfaceID& AthenaRootStreamerSvc::type() const
105 {
107 }
108 
109 
110 StatusCode AthenaRootStreamerSvc::AddStreamer(const std::string& converter_classname, bool adopt)
111 {
112  RootType streamer_class( converter_classname );
113  if( !streamer_class ) {
114 
115  // Enable library auto-loading. Only once per job.
116  static std::once_flag libLoadFlag;
117  std::call_once( libLoadFlag, []( TInterpreter& interpreter ) {
118 
119  // Enable library auto-loading.
120  TClass::ReadRules();
121  interpreter.LoadLibraryMap();
122  interpreter.SetClassAutoloading( true );
123 
124  }, *gInterpreter );
125 
126  // int ntypesBefore = Reflex::Type::TypeSize();
127  gInterpreter->AutoLoad( converter_classname.c_str() );
128 
129  MsgStream log(msgSvc(), name());
130  streamer_class = RootType( converter_classname );
131  if( ! streamer_class ) {
132  ATH_MSG_ERROR ( "Could not find <" << converter_classname
133  << "> in the dictionary, and autoloading failed" );
134  return(StatusCode::FAILURE);
135  }
136  log << MSG::DEBUG << "Loaded dictionary for class " << converter_classname
137  // << " ntypes before load " << ntypesBefore
138  // << " ntypes loaded " << Reflex::Type::TypeSize() - ntypesBefore
139  << endmsg;
140  }
141  void* obj = streamer_class.Construct();
142  m_createdConverters.emplace_back( streamer_class, obj );
143  return AddStreamer( (T_AthenaRootConverterBase*)obj, adopt);
144 }
145 
146 
148 {
149  const std::string &classname = converter->ClassName();
150  AthenaRootStreamer* & streamer = m_streamerMap[classname];
151  if (!streamer) {
152  // no streamer for this class yet
153  streamer = new AthenaRootStreamer(classname, this);
154  }
155  auto convH = std::make_unique<AthenaRootConverterHandle>(converter);
156  if( streamer->AddConverter(std::move(convH)).isFailure() ) {
157  ATH_MSG_ERROR ( "ROOT Streamer for " << classname
158  << " already has a converter for checksum = "
159  << converter->StreamerChecksum() );
160  return(StatusCode::FAILURE);
161  }
162  ATH_MSG_INFO ( "ROOT Streamer for " << classname
163  << " added converter for checksum = "
164  << converter->StreamerChecksum() );
165 
166  if( adopt ) {
167  return AdoptStreamerForClass( classname );
168  }
169  return(StatusCode::SUCCESS);
170 }
171 
172 
173 
175  if (m_streamerMap.find(class_name) == m_streamerMap.end()) {
176  ATH_MSG_ERROR ( "Attemt to adopt streamer for "
177  << class_name
178  << " with has no converters defined" );
179  return(StatusCode::FAILURE);
180  }
181  if (m_streamerMap[class_name]->Adopt().isSuccess()) {
182  ATH_MSG_INFO ( "Adopted streamer for class " << class_name );
183  return(StatusCode::SUCCESS);
184  }
185  ATH_MSG_ERROR ( "Failed to adopt streamer for " << class_name );
186  return(StatusCode::FAILURE);
187 }
188 
189 
190 
192 {
193  StatusCode sc = StatusCode::SUCCESS;
194  for (auto& p : m_streamerMap) {
195  if( p.second->Adopt().isFailure() ) {
196  ATH_MSG_INFO ( "Failed to adopt streamer for class " << p.first );
197  sc = StatusCode::FAILURE;
198  }
199  }
200  return sc;
201 }
202 
203 
AthenaRootStreamerSvc
This class provides the manager for ROOT custom streamers.
Definition: AthenaRootStreamerSvc.h:31
pool::DbSession::close
DbStatus close()
Close the session.
T_AthenaRootConverterBase
Definition: T_AthenaRootConverter.h:17
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:53
IAthenaRootStreamerSvc::interfaceID
static const InterfaceID & interfaceID()
Retrieve interface ID.
Definition: IAthenaRootStreamerSvc.h:71
pool::DbStatus
Definition: DbStatus.h:67
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
AthenaRootStreamerSvc::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvInterface)
Required of all Gaudi services: see Gaudi documentation for details.
Definition: AthenaRootStreamerSvc.cxx:91
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthenaRootStreamer.h
this file contains the class definition for the AthenaRootStreamer class.
initialize
void initialize()
Definition: run_EoverP.cxx:894
AthenaRootStreamerSvc::m_streamerMap
StreamerMap m_streamerMap
Definition: AthenaRootStreamerSvc.h:64
pool::DbSession
Db objects: class DbSession.
Definition: DbSession.h:43
T_AthenaRootConverterBase::ClassName
const std::string & ClassName()
Definition: T_AthenaRootConverter.h:27
AthenaRootStreamerSvc::type
virtual const InterfaceID & type() const
Service type.
Definition: AthenaRootStreamerSvc.cxx:104
DbSession.h
AthenaRootStreamer::AddConverter
StatusCode AddConverter(std::unique_ptr< AthenaRootConverterHandle > converter)
Add a converter to this streamer.
Definition: AthenaRootStreamer.cxx:36
AthenaRootStreamerSvc::AdoptStreamerForClass
virtual StatusCode AdoptStreamerForClass(const std::string &class_name)
Adopt ROOT custom streamer for a given class.
Definition: AthenaRootStreamerSvc.cxx:174
T_AthenaRootConverterBase::StreamerChecksum
unsigned StreamerChecksum()
Definition: T_AthenaRootConverter.h:28
RootType
TTypeAdapter RootType
Definition: RootType.h:211
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthenaRootStreamerSvc::m_createdConverters
ConverterVector_t m_createdConverters
Definition: AthenaRootStreamerSvc.h:70
AthenaRootStreamerSvc::finalize
virtual StatusCode finalize()
Required of all Gaudi services:
Definition: AthenaRootStreamerSvc.cxx:75
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
AthenaRootConverterHandle.h
his file contains the class definition for AthenaRootConverter class.
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
lumiFormat.i
int i
Definition: lumiFormat.py:92
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
AthService
Definition: AthService.h:32
pool::DbSession::open
DbStatus open()
Open the session in a given mode.
AthenaRootStreamer
This class enhances ROOT custom streamer base TClassStreamer and can choose a converter function base...
Definition: AthenaRootStreamer.h:33
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TScopeAdapter::Construct
void * Construct() const
Definition: RootType.cxx:661
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
AthenaRootStreamerSvc::AddStreamer
virtual StatusCode AddStreamer(const std::string &converter_classname, bool adopt=true)
Create (or exetend) ROOT streamer Class name for which the streamer is added is extracted from the co...
Definition: AthenaRootStreamerSvc.cxx:110
AthenaRootStreamerSvc::AdoptAllStreamers
virtual StatusCode AdoptAllStreamers()
Adopt all ROOT streamers known to the service.
Definition: AthenaRootStreamerSvc.cxx:191
AthenaRootStreamerSvc::~AthenaRootStreamerSvc
virtual ~AthenaRootStreamerSvc()
Destructor.
Definition: AthenaRootStreamerSvc.cxx:36
DEBUG
#define DEBUG
Definition: page_access.h:11
pool::DbSession::db
IOODatabase * db(const DbType &typ)
Allow access to the Database implementation.
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
AthenaRootStreamerSvc.h
Athena ROOT Streaming Service class.
RootType.h
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
T_AthenaRootConverter.h
Athena ROOT Streaming Converter - template class to be extended by a user prividing a conversion func...
merge.status
status
Definition: merge.py:17
python.DetectStreamerInfoChanges.class_name
class_name
Definition: DetectStreamerInfoChanges.py:57
AthenaRootStreamerSvc::AthenaRootStreamerSvc
AthenaRootStreamerSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard Service Constructor.
Definition: AthenaRootStreamerSvc.cxx:28
AthenaRootStreamerSvc::initialize
virtual StatusCode initialize()
Required of all Gaudi services:
Definition: AthenaRootStreamerSvc.cxx:41
python.PyAthena.obj
obj
Definition: PyAthena.py:135
pool::DbStatus::Success
@ Success
Definition: DbStatus.h:73
AthenaRootStreamerSvc::m_streamerClassNames
StringArrayProperty m_streamerClassNames
Definition: AthenaRootStreamerSvc.h:60
TScopeAdapter
Definition: RootType.h:119