The Gaudi Framework  v32r2 (46d42edc)
DataObjectHandleBase.cpp
Go to the documentation of this file.
2 #include "GaudiKernel/AlgTool.h"
6 #include <Gaudi/Algorithm.h>
7 
8 #include <boost/tokenizer.hpp>
9 #include <ostream>
10 #include <sstream>
11 #include <string>
12 
14 
16 
17 //---------------------------------------------------------------------------
19  : Gaudi::DataHandle( other )
20  , m_EDS( std::move( other.m_EDS ) )
21  , m_MS( std::move( other.m_MS ) )
22  , m_init( other.m_init )
23  , m_optional( other.m_optional )
24  , m_wasRead( other.m_wasRead )
25  , m_wasWritten( other.m_wasWritten )
26  , m_searchDone( other.m_searchDone ) {
27  m_owner->declare( *this );
28 }
29 
30 //---------------------------------------------------------------------------
32  // avoid modification of searchDone in other while we are copying
34  // FIXME: operator= should not change our owner, only our 'value'
35  Gaudi::DataHandle::operator=( other );
36  m_EDS = other.m_EDS;
37  m_MS = other.m_MS;
38  m_init = other.m_init;
39  m_optional = other.m_optional;
40  m_wasRead = other.m_wasRead;
41  m_wasWritten = other.m_wasWritten;
42  m_searchDone = other.m_searchDone;
43  return *this;
44 }
45 
46 //---------------------------------------------------------------------------
48  : Gaudi::DataHandle( k, a, owner ) {
49  m_owner->declare( *this );
50 }
51 
52 //---------------------------------------------------------------------------
53 
55  : DataObjectHandleBase( DataObjID( k ), a, owner ) {}
56 
57 //---------------------------------------------------------------------------
59 
60 //---------------------------------------------------------------------------
62  DataObject* p = nullptr;
63  if ( LIKELY( m_searchDone ) ) { // fast path: searchDone, objKey is in its final state
64  m_EDS->retrieveObject( objKey(), p ).ignore();
65  return p;
66  }
67 
68  // slow path -- move into seperate function to improve code generation?
69 
70  // convenience towards users -- remind them to register
71  // but as m_MS is not yet set, we cannot use a MsgStream...
72  if ( !m_init ) {
73  std::cerr << ( owner() ? owner()->name() : "<UNKNOWN>:" ) << "DataObjectHandle: uninitialized data handle"
74  << std::endl;
75  }
76 
77  // as m_searchDone is not true yet, objKey may change... so in this
78  // branch we _first_ grab the mutex, to avoid objKey changing while we use it
79 
80  // take a lock to be sure we only execute this once at a time
82 
83  StatusCode sc = m_EDS->retrieveObject( objKey(), p );
84  if ( m_searchDone ) { // another thread has done the search while we were blocked
85  // on the mutex. As a result, nothing left to do but return...
86  sc.ignore();
87  return p;
88  }
89 
90  if ( !sc.isSuccess() ) {
91  auto tokens = boost::tokenizer<boost::char_separator<char>>{objKey(), boost::char_separator<char>{":"}};
92  // let's try our alternatives (if any)
93  auto alt = std::find_if( tokens.begin(), tokens.end(),
94  [&]( const std::string& n ) { return m_EDS->retrieveObject( n, p ).isSuccess(); } );
95  if ( alt != tokens.end() ) {
96  MsgStream log( m_MS, owner()->name() + ":DataObjectHandle" );
97  log << MSG::DEBUG << ": could not find \"" << objKey() << "\" -- using alternative source: \"" << *alt
98  << "\" instead" << endmsg;
99  // found something -- set it as default; this is not atomic, but
100  // at least in `fetch` there is no use of `objKey` that races with
101  // this assignment... (but there may be others!)
102  setKey( *alt );
103  }
104  }
105  m_searchDone = true;
106  return p;
107 }
108 
109 //---------------------------------------------------------------------------
110 
112 
113 //---------------------------------------------------------------------------
115  std::string m;
116  switch ( mode() ) {
118  m = "R";
119  break;
120  case Gaudi::DataHandle::Mode::Writer:
121  m = "W";
122  break;
123  default:
124  m = "UNKNOWN";
125  break;
126  }
127  return "DataObjectHandleBase('" + toString() + "', '" + m + "', '" + default_type + "')";
128 }
129 
130 //---------------------------------------------------------------------------
132 
133 //---------------------------------------------------------------------------
134 
136 
137  assert( !m_init );
138 
139  if ( !owner() ) return false;
140 
141  setRead( false );
142  setWritten( false );
143 
144  Gaudi::Algorithm* algorithm = dynamic_cast<Gaudi::Algorithm*>( owner() );
145  if ( algorithm ) {
146  // Fetch the event Data Service from the algorithm
147  m_EDS = algorithm->evtSvc();
148  m_MS = algorithm->msgSvc();
149  } else {
150  AlgTool* tool = dynamic_cast<AlgTool*>( owner() );
151  if ( tool ) {
152  m_EDS = tool->evtSvc();
153  m_MS = tool->msgSvc();
154  } else {
155  throw GaudiException( "owner is neither AlgTool nor Gaudi::Algorithm", "Invalid Cast", StatusCode::FAILURE );
156  }
157  }
158  m_init = true;
159  return true;
160 }
161 
162 //---------------------------------------------------------------------------
163 
165 
166 //---------------------------------------------------------------------------
167 
169 
170  str << d.fullKey() << " m: " << d.mode();
171  if ( d.owner() ) str << " o: " << d.owner()->name();
172  str << " opt: " << d.isOptional();
173  return str;
174 }
virtual Mode mode() const
Definition: DataHandle.h:42
void setWritten(bool wasWritten=true)
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
Define general base for Gaudi exception.
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
virtual void declare(Gaudi::DataHandle &)=0
static const std::string default_type
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:40
std::string pythonRepr() const override
T endl(T... args)
virtual const std::string & objKey() const
Definition: DataHandle.h:47
SmartIF< IDataProviderSvc > m_EDS
SmartIF< IDataProviderSvc > & evtSvc() const
shortcut for method eventSvc
Definition: Algorithm.h:265
STL namespace.
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
virtual void renounce(Gaudi::DataHandle &)=0
virtual void setKey(const DataObjID &key) const
Definition: DataHandle.h:44
void setRead(bool wasRead=true)
bool m_searchDone
Whether the search part of the fetch method (so dealing with alt names was already executed or not.
Provide serialization function (output only) for some common STL classes (vectors,...
virtual const std::string & name() const =0
Retrieve the name of the instance.
STL class.
DataObjectHandleBase & operator=(const DataObjectHandleBase &)
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:48
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
constexpr double m
Definition: SystemOfUnits.h:92
std::ostream & operator<<(std::ostream &str, const DataObjectHandleBase &d)
bool isOptional() const
Check if the data object declared is optional for the algorithm.
IDataHandleHolder * m_owner
Definition: DataHandle.h:66
const DataObjID INVALID_DATAOBJID
bool isSuccess() const
Definition: StatusCode.h:267
void fromString(const std::string &s)
#define LIKELY(x)
Definition: Kernel.h:95
T find_if(T... args)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
virtual StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
DataObject * fetch() const
std::mutex m_searchMutex
A Mutex protecting the calls to the search part of the fetch method, so that we are sure that we only...
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:47
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:79
string s
Definition: gaudirun.py:318
constexpr static const auto FAILURE
Definition: StatusCode.h:86
std::string toString() const
SmartIF< IMessageSvc > m_MS
IDataProviderSvc * evtSvc() const
accessor to event service service
Definition: AlgTool.cpp:88
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
def Reader(readerType, filename, qacross, qToEngine)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
DataObjectHandleBase(const DataObjID &k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)