The Gaudi Framework  v30r4 (9b837755)
DataObjectHandleBase.cpp
Go to the documentation of this file.
2 #include "GaudiKernel/AlgTool.h"
7 
8 #include <boost/tokenizer.hpp>
9 #include <ostream>
10 #include <sstream>
11 #include <string>
12 
14 
15 //---------------------------------------------------------------------------
17  : Gaudi::v1::DataHandle( other )
18  , m_EDS( std::move( other.m_EDS ) )
19  , m_MS( std::move( other.m_MS ) )
20  , m_init( other.m_init )
21  , m_optional( other.m_optional )
22  , m_wasRead( other.m_wasRead )
23  , m_wasWritten( other.m_wasWritten )
24  , m_searchDone( other.m_searchDone )
25 {
26  m_owner->declare( *this );
27 }
28 
29 //---------------------------------------------------------------------------
31 {
32  // avoid modification of searchDone in other while we are copying
34  // FIXME: operator= should not change our owner, only our 'value'
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 //---------------------------------------------------------------------------
49  : Gaudi::v1::DataHandle( k, a, owner )
50 {
51  m_owner->declare( *this );
52 }
53 
54 //---------------------------------------------------------------------------
55 
58  : DataObjectHandleBase( DataObjID( k ), a, owner )
59 {
60 }
61 
62 //---------------------------------------------------------------------------
64 
65 //---------------------------------------------------------------------------
67 {
68  DataObject* p = nullptr;
69  if ( LIKELY( m_searchDone ) ) { // fast path: searchDone, objKey is in its final state
70  m_EDS->retrieveObject( objKey(), p ).ignore();
71  return p;
72  }
73 
74  // slow path -- move into seperate function to improve code generation?
75 
76  // convenience towards users -- remind them to register
77  // but as m_MS is not yet set, we cannot use a MsgStream...
78  if ( !m_init ) {
79  std::cerr << ( owner() ? owner()->name() : "<UNKNOWN>:" ) << "DataObjectHandle: uninitialized data handle"
80  << std::endl;
81  }
82 
83  // as m_searchDone is not true yet, objKey may change... so in this
84  // branch we _first_ grab the mutex, to avoid objKey changing while we use it
85 
86  // take a lock to be sure we only execute this once at a time
88 
89  StatusCode sc = m_EDS->retrieveObject( objKey(), p );
90  if ( m_searchDone ) { // another thread has done the search while we were blocked
91  // on the mutex. As a result, nothing left to do but return...
92  sc.ignore();
93  return p;
94  }
95 
96  if ( !sc.isSuccess() ) {
97  auto tokens = boost::tokenizer<boost::char_separator<char>>{objKey(), boost::char_separator<char>{":"}};
98  // let's try our alternatives (if any)
99  auto alt = std::find_if( tokens.begin(), tokens.end(),
100  [&]( const std::string& n ) { return m_EDS->retrieveObject( n, p ).isSuccess(); } );
101  if ( alt != tokens.end() ) {
102  MsgStream log( m_MS, owner()->name() + ":DataObjectHandle" );
103  log << MSG::DEBUG << ": could not find \"" << objKey() << "\" -- using alternative source: \"" << *alt
104  << "\" instead" << endmsg;
105  // found something -- set it as default; this is not atomic, but
106  // at least in `fetch` there is no use of `objKey` that races with
107  // this assignment... (but there may be others!)
108  setKey( *alt );
109  }
110  }
111  m_searchDone = true;
112  return p;
113 }
114 
115 //---------------------------------------------------------------------------
116 
118 
119 //---------------------------------------------------------------------------
120 std::string DataObjectHandleBase::pythonRepr() const { return "DataObjectHandleBase(\"" + toString() + "\")"; }
121 
122 //---------------------------------------------------------------------------
124 
125 //---------------------------------------------------------------------------
126 
128 {
129 
130  assert( !m_init );
131 
132  if ( !owner() ) return false;
133 
134  setRead( false );
135  setWritten( false );
136 
137  Algorithm* algorithm = dynamic_cast<Algorithm*>( owner() );
138  if ( algorithm ) {
139  // Fetch the event Data Service from the algorithm
140  m_EDS = algorithm->evtSvc();
141  m_MS = algorithm->msgSvc();
142  } else {
143  AlgTool* tool = dynamic_cast<AlgTool*>( owner() );
144  if ( tool ) {
145  m_EDS = tool->evtSvc();
146  m_MS = tool->msgSvc();
147  } else {
148  throw GaudiException( "owner is neither AlgTool nor Algorithm", "Invalid Cast", StatusCode::FAILURE );
149  }
150  }
151  m_init = true;
152  return true;
153 }
154 
155 //---------------------------------------------------------------------------
156 
158 
159 //---------------------------------------------------------------------------
160 
162 {
163 
164  str << d.fullKey() << " m: " << d.mode();
165  if ( d.owner() ) str << " o: " << d.owner()->name();
166  str << " opt: " << d.isOptional();
167  return str;
168 }
IDataProviderSvc * evtSvc() const
accessor to event service service
Definition: AlgTool.h:113
constexpr static const auto FAILURE
Definition: StatusCode.h:88
void setWritten(bool wasWritten=true)
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
Define general base for Gaudi exception.
bool isSuccess() const
Definition: StatusCode.h:287
T endl(T...args)
SmartIF< IDataProviderSvc > m_EDS
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:48
STL namespace.
IDataHandleHolder * m_owner
Definition: DataHandle.h:74
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
DataObjectHandleBase(const DataObjID &k, Gaudi::v1::DataHandle::Mode a, IDataHandleHolder *owner)
void setRead(bool wasRead=true)
std::string toString() const
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, lists, pairs, maps) plus GaudiUtils::Map and GaudiUtils::HashMap.
PropertyMgr & operator=(const PropertyMgr &)=delete
STL class.
DataObjectHandleBase & operator=(const DataObjectHandleBase &)
Entity which holds DataHandles and can track the associated data dependencies for the Scheduler...
DataHandle(const DataObjID &k, Mode a=Reader, IDataHandleHolder *owner=nullptr)
Definition: DataHandle.h:39
virtual void renounce(Gaudi::v1::DataHandle &)=0
Discard ownership of a legacy DataHandle.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:56
virtual Mode mode() const
Definition: DataHandle.h:50
const DataObjID INVALID_DATAOBJID
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
virtual void setKey(const DataObjID &key) const
Definition: DataHandle.h:52
virtual StatusCode retrieveObject(IRegistry *pDirectory, boost::string_ref path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
void fromString(const std::string &s)
#define LIKELY(x)
Definition: Kernel.h:88
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:79
T find_if(T...args)
SmartIF< IDataProviderSvc > & evtSvc() const
shortcut for method eventSvc
Definition: Algorithm.h:281
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
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...
virtual void declare(Gaudi::v1::DataHandle &)=0
Declare ownership of a legacy DataHandle.
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:47
string s
Definition: gaudirun.py:253
std::string pythonRepr() const override
DataObject * fetch() const
SmartIF< IMessageSvc > m_MS
virtual const std::string & objKey() const
Definition: DataHandle.h:55
bool isOptional() const
Check if the data object declared is optional for the algorithm.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
friend std::ostream & operator<<(std::ostream &str, const DataObjectHandleBase &d)
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209