The Gaudi Framework  v33r1 (b1225454)
DataObjectHandleBase.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
12 #include "GaudiKernel/AlgTool.h"
16 #include <Gaudi/Algorithm.h>
17 
18 #include <boost/tokenizer.hpp>
19 #include <ostream>
20 #include <sstream>
21 #include <string>
22 
24 
26 
27 //---------------------------------------------------------------------------
29  : Gaudi::DataHandle( other )
30  , m_EDS( std::move( other.m_EDS ) )
31  , m_MS( std::move( other.m_MS ) )
32  , m_init( other.m_init )
33  , m_optional( other.m_optional )
34  , m_wasRead( other.m_wasRead )
35  , m_wasWritten( other.m_wasWritten )
36  , m_searchDone( other.m_searchDone ) {
37  m_owner->declare( *this );
38 }
39 
40 //---------------------------------------------------------------------------
42  // avoid modification of searchDone in other while we are copying
43  auto guard = std::scoped_lock{other.m_searchMutex};
44  // FIXME: operator= should not change our owner, only our 'value'
45  Gaudi::DataHandle::operator=( other );
46  m_EDS = other.m_EDS;
47  m_MS = other.m_MS;
48  m_init = other.m_init;
49  m_optional = other.m_optional;
50  m_wasRead = other.m_wasRead;
51  m_wasWritten = other.m_wasWritten;
52  m_searchDone = other.m_searchDone;
53  return *this;
54 }
55 
56 //---------------------------------------------------------------------------
58  : Gaudi::DataHandle( k, a, owner ) {
59  m_owner->declare( *this );
60 }
61 
62 //---------------------------------------------------------------------------
63 
65  : DataObjectHandleBase( DataObjID( k ), a, owner ) {}
66 
67 //---------------------------------------------------------------------------
69 
70 //---------------------------------------------------------------------------
72  DataObject* p = nullptr;
73  if ( LIKELY( m_searchDone ) ) { // fast path: searchDone, objKey is in its final state
74  m_EDS->retrieveObject( objKey(), p ).ignore();
75  return p;
76  }
77 
78  // slow path -- move into seperate function to improve code generation?
79 
80  // convenience towards users -- remind them to register
81  // but as m_MS is not yet set, we cannot use a MsgStream...
82  if ( !m_init ) {
83  std::cerr << ( owner() ? owner()->name() : "<UNKNOWN>:" ) << "DataObjectHandle: uninitialized data handle"
84  << std::endl;
85  }
86 
87  // as m_searchDone is not true yet, objKey may change... so in this
88  // branch we _first_ grab the mutex, to avoid objKey changing while we use it
89 
90  // take a lock to be sure we only execute this once at a time
91  auto guard = std::scoped_lock{m_searchMutex};
92 
93  StatusCode sc = m_EDS->retrieveObject( objKey(), p );
94  if ( m_searchDone ) { // another thread has done the search while we were blocked
95  // on the mutex. As a result, nothing left to do but return...
96  sc.ignore();
97  return p;
98  }
99 
100  if ( !sc.isSuccess() ) {
101  auto tokens = boost::tokenizer<boost::char_separator<char>>{objKey(), boost::char_separator<char>{":"}};
102  // let's try our alternatives (if any)
103  auto alt = std::find_if( tokens.begin(), tokens.end(),
104  [&]( const std::string& n ) { return m_EDS->retrieveObject( n, p ).isSuccess(); } );
105  if ( alt != tokens.end() ) {
106  MsgStream log( m_MS, owner()->name() + ":DataObjectHandle" );
107  log << MSG::DEBUG << ": could not find \"" << objKey() << "\" -- using alternative source: \"" << *alt
108  << "\" instead" << endmsg;
109  // found something -- set it as default; this is not atomic, but
110  // at least in `fetch` there is no use of `objKey` that races with
111  // this assignment... (but there may be others!)
112  setKey( *alt );
113  }
114  }
115  m_searchDone = true;
116  return p;
117 }
118 
119 //---------------------------------------------------------------------------
120 
122 
123 //---------------------------------------------------------------------------
125  std::string m;
126  switch ( mode() ) {
128  m = "R";
129  break;
130  case Gaudi::DataHandle::Mode::Writer:
131  m = "W";
132  break;
133  default:
134  m = "UNKNOWN";
135  break;
136  }
137  return "DataObjectHandleBase('" + toString() + "', '" + m + "', '" + default_type + "')";
138 }
139 
140 //---------------------------------------------------------------------------
142 
143 //---------------------------------------------------------------------------
144 
146 
147  assert( !m_init );
148 
149  if ( !owner() ) return false;
150 
151  setRead( false );
152  setWritten( false );
153 
154  Gaudi::Algorithm* algorithm = dynamic_cast<Gaudi::Algorithm*>( owner() );
155  if ( algorithm ) {
156  // Fetch the event Data Service from the algorithm
157  m_EDS = algorithm->evtSvc();
158  m_MS = algorithm->msgSvc();
159  } else {
160  AlgTool* tool = dynamic_cast<AlgTool*>( owner() );
161  if ( tool ) {
162  m_EDS = tool->evtSvc();
163  m_MS = tool->msgSvc();
164  } else {
165  throw GaudiException( "owner is neither AlgTool nor Gaudi::Algorithm", "Invalid Cast", StatusCode::FAILURE );
166  }
167  }
168  m_init = true;
169  return true;
170 }
171 
172 //---------------------------------------------------------------------------
173 
175 
176 //---------------------------------------------------------------------------
177 
179 
180  str << d.fullKey() << " m: " << d.mode();
181  if ( d.owner() ) str << " o: " << d.owner()->name();
182  str << " opt: " << d.isOptional();
183  return str;
184 }
virtual Mode mode() const
Definition: DataHandle.h:52
void setWritten(bool wasWritten=true)
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
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:50
std::string pythonRepr() const override
T endl(T... args)
virtual const std::string & objKey() const
Definition: DataHandle.h:57
SmartIF< IDataProviderSvc > m_EDS
SmartIF< IDataProviderSvc > & evtSvc() const
shortcut for method eventSvc
Definition: Algorithm.h:249
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
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:58
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
constexpr double m
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:76
const DataObjID INVALID_DATAOBJID
bool isSuccess() const
Definition: StatusCode.h:365
void fromString(const std::string &s)
#define LIKELY(x)
Definition: Kernel.h:105
T find_if(T... args)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:168
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:57
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:89
string s
Definition: gaudirun.py:328
constexpr static const auto FAILURE
Definition: StatusCode.h:101
virtual void setKey(DataObjID key) const
Definition: DataHandle.h:54
std::string toString() const
SmartIF< IMessageSvc > m_MS
IDataProviderSvc * evtSvc() const
accessor to event service service
Definition: AlgTool.cpp:98
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:40
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:202
DataObjectHandleBase(const DataObjID &k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)