ATLAS Offline Software
AthenaRootStreamerSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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  : base_class(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 const InterfaceID& AthenaRootStreamerSvc::type() const
92 {
93  return IAthenaRootStreamerSvc::interfaceID();
94 }
95 
96 
97 StatusCode AthenaRootStreamerSvc::AddStreamer(const std::string& converter_classname, bool adopt)
98 {
99  RootType streamer_class( converter_classname );
100  if( !streamer_class ) {
101 
102  // Enable library auto-loading. Only once per job.
103  static std::once_flag libLoadFlag;
104  std::call_once( libLoadFlag, []( TInterpreter& interpreter ) {
105 
106  // Enable library auto-loading.
107  TClass::ReadRules();
108  interpreter.LoadLibraryMap();
109  interpreter.SetClassAutoloading( true );
110 
111  }, *gInterpreter );
112 
113  // int ntypesBefore = Reflex::Type::TypeSize();
114  gInterpreter->AutoLoad( converter_classname.c_str() );
115 
116  MsgStream log(msgSvc(), name());
117  streamer_class = RootType( converter_classname );
118  if( ! streamer_class ) {
119  ATH_MSG_ERROR ( "Could not find <" << converter_classname
120  << "> in the dictionary, and autoloading failed" );
121  return(StatusCode::FAILURE);
122  }
123  log << MSG::DEBUG << "Loaded dictionary for class " << converter_classname
124  // << " ntypes before load " << ntypesBefore
125  // << " ntypes loaded " << Reflex::Type::TypeSize() - ntypesBefore
126  << endmsg;
127  }
128  void* obj = streamer_class.Construct();
129  m_createdConverters.emplace_back( streamer_class, obj );
130  return AddStreamer( (T_AthenaRootConverterBase*)obj, adopt);
131 }
132 
133 
135 {
136  const std::string &classname = converter->ClassName();
137  AthenaRootStreamer* & streamer = m_streamerMap[classname];
138  if (!streamer) {
139  // no streamer for this class yet
140  streamer = new AthenaRootStreamer(classname, this);
141  }
142  auto convH = std::make_unique<AthenaRootConverterHandle>(converter);
143  if( streamer->AddConverter(std::move(convH)).isFailure() ) {
144  ATH_MSG_ERROR ( "ROOT Streamer for " << classname
145  << " already has a converter for checksum = "
146  << converter->StreamerChecksum() );
147  return(StatusCode::FAILURE);
148  }
149  ATH_MSG_INFO ( "ROOT Streamer for " << classname
150  << " added converter for checksum = "
151  << converter->StreamerChecksum() );
152 
153  if( adopt ) {
154  return AdoptStreamerForClass( classname );
155  }
156  return(StatusCode::SUCCESS);
157 }
158 
159 
160 
162  if (m_streamerMap.find(class_name) == m_streamerMap.end()) {
163  ATH_MSG_ERROR ( "Attemt to adopt streamer for "
164  << class_name
165  << " with has no converters defined" );
166  return(StatusCode::FAILURE);
167  }
168  if (m_streamerMap[class_name]->Adopt().isSuccess()) {
169  ATH_MSG_INFO ( "Adopted streamer for class " << class_name );
170  return(StatusCode::SUCCESS);
171  }
172  ATH_MSG_ERROR ( "Failed to adopt streamer for " << class_name );
173  return(StatusCode::FAILURE);
174 }
175 
176 
177 
179 {
180  StatusCode sc = StatusCode::SUCCESS;
181  for (auto& p : m_streamerMap) {
182  if( p.second->Adopt().isFailure() ) {
183  ATH_MSG_INFO ( "Failed to adopt streamer for class " << p.first );
184  sc = StatusCode::FAILURE;
185  }
186  }
187  return sc;
188 }
189 
190 
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:50
pool::DbStatus
Definition: DbStatus.h:67
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:61
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:91
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)
Definition: AthenaRootStreamerSvc.cxx:161
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:67
AthenaRootStreamerSvc::finalize
virtual StatusCode finalize()
Required of all Gaudi services:
Definition: AthenaRootStreamerSvc.cxx:75
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
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:85
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
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:228
AthenaRootStreamerSvc::AddStreamer
virtual StatusCode AddStreamer(const std::string &converter_classname, bool adopt=true)
Definition: AthenaRootStreamerSvc.cxx:97
AthenaRootStreamerSvc::AdoptAllStreamers
virtual StatusCode AdoptAllStreamers()
Definition: AthenaRootStreamerSvc.cxx:178
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
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:60
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:132
pool::DbStatus::Success
@ Success
Definition: DbStatus.h:73
AthenaRootStreamerSvc::m_streamerClassNames
StringArrayProperty m_streamerClassNames
Definition: AthenaRootStreamerSvc.h:57
TScopeAdapter
Definition: RootType.h:119