The Gaudi Framework  v36r1 (3e2fb5a8)
DataObjectHandleBase.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2020 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 
25 //---------------------------------------------------------------------------
27  : Gaudi::DataHandle( other )
28  , m_EDS( std::move( other.m_EDS ) )
29  , m_MS( std::move( other.m_MS ) )
30  , m_init( other.m_init )
31  , m_optional( other.m_optional )
32  , m_wasRead( other.m_wasRead )
33  , m_wasWritten( other.m_wasWritten )
34  , m_searchDone( other.m_searchDone ) {
35  m_owner->declare( *this );
36 }
37 
38 //---------------------------------------------------------------------------
40  // avoid modification of searchDone in other while we are copying
41  auto guard = std::scoped_lock{other.m_searchMutex};
42  // FIXME: operator= should not change our owner, only our 'value'
43  Gaudi::DataHandle::operator=( other );
44  m_EDS = other.m_EDS;
45  m_MS = other.m_MS;
46  m_init = other.m_init;
47  m_optional = other.m_optional;
48  m_wasRead = other.m_wasRead;
49  m_wasWritten = other.m_wasWritten;
50  m_searchDone = other.m_searchDone;
51  return *this;
52 }
53 
54 //---------------------------------------------------------------------------
56  : Gaudi::DataHandle( k, a, owner ) {
57  m_owner->declare( *this );
58 }
59 
60 //---------------------------------------------------------------------------
61 
63  : DataObjectHandleBase( DataObjID( k ), a, owner ) {}
64 
65 //---------------------------------------------------------------------------
67 
68 //---------------------------------------------------------------------------
70  DataObject* p = nullptr;
71  if ( LIKELY( m_searchDone ) ) { // fast path: searchDone, objKey is in its final state
72  m_EDS->retrieveObject( objKey(), p ).ignore();
73  return p;
74  }
75 
76  // slow path -- move into seperate function to improve code generation?
77 
78  // convenience towards users -- remind them to register
79  // but as m_MS is not yet set, we cannot use a MsgStream...
80  if ( !m_init ) {
81  std::cerr << ( owner() ? owner()->name() : "<UNKNOWN>:" ) << "DataObjectHandle: uninitialized data handle"
82  << std::endl;
83  }
84 
85  // as m_searchDone is not true yet, objKey may change... so in this
86  // branch we _first_ grab the mutex, to avoid objKey changing while we use it
87 
88  // take a lock to be sure we only execute this once at a time
89  auto guard = std::scoped_lock{m_searchMutex};
90 
91  StatusCode sc = m_EDS->retrieveObject( objKey(), p );
92  if ( m_searchDone ) { // another thread has done the search while we were blocked
93  // on the mutex. As a result, nothing left to do but return...
94  sc.ignore();
95  return p;
96  }
97 
98  if ( !sc.isSuccess() ) {
99  auto tokens = boost::tokenizer<boost::char_separator<char>>{objKey(), boost::char_separator<char>{":"}};
100  // let's try our alternatives (if any)
101  auto alt = std::find_if( tokens.begin(), tokens.end(),
102  [&]( const std::string& n ) { return m_EDS->retrieveObject( n, p ).isSuccess(); } );
103  if ( alt != tokens.end() ) {
104  MsgStream log( m_MS, owner()->name() + ":DataObjectHandle" );
105  log << MSG::DEBUG << ": could not find \"" << objKey() << "\" -- using alternative source: \"" << *alt
106  << "\" instead" << endmsg;
107  // found something -- set it as default; this is not atomic, but
108  // at least in `fetch` there is no use of `objKey` that races with
109  // this assignment... (but there may be others!)
110  setKey( *alt );
111  }
112  }
113  m_searchDone = true;
114  return p;
115 }
116 
117 //---------------------------------------------------------------------------
118 
120 
121  assert( !m_init );
122 
123  if ( !owner() ) return false;
124 
125  setRead( false );
126  setWritten( false );
127 
128  Gaudi::Algorithm* algorithm = dynamic_cast<Gaudi::Algorithm*>( owner() );
129  if ( algorithm ) {
130  // Fetch the event Data Service from the algorithm
131  m_EDS = algorithm->evtSvc();
132  m_MS = algorithm->msgSvc();
133  } else {
134  AlgTool* tool = dynamic_cast<AlgTool*>( owner() );
135  if ( tool ) {
136  m_EDS = tool->evtSvc();
137  m_MS = tool->msgSvc();
138  } else {
139  throw GaudiException( "owner is neither AlgTool nor Gaudi::Algorithm", "Invalid Cast", StatusCode::FAILURE );
140  }
141  }
142  m_init = true;
143  return true;
144 }
145 
146 //---------------------------------------------------------------------------
147 
149 
150 //---------------------------------------------------------------------------
151 
153 
154  str << d.fullKey() << " m: " << d.mode();
155  if ( d.owner() ) str << " o: " << d.owner()->name();
156  str << " opt: " << d.isOptional();
157  return str;
158 }
IDataHandleHolder
Definition: IDataHandleHolder.h:24
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
std::string
STL class.
Gaudi.Configuration.log
log
Definition: Configuration.py:24
DataObjectHandleBase::m_wasWritten
bool m_wasWritten
Definition: DataObjectHandleBase.h:83
DataObjectHandleBase::m_EDS
SmartIF< IDataProviderSvc > m_EDS
Definition: DataObjectHandleBase.h:77
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:355
DataObjectHandleBase::m_MS
SmartIF< IMessageSvc > m_MS
Definition: DataObjectHandleBase.h:78
operator<<
std::ostream & operator<<(std::ostream &str, const DataObjectHandleBase &d)
Definition: DataObjectHandleBase.cpp:152
std::find_if
T find_if(T... args)
DataObjectHandleBase::m_searchDone
bool m_searchDone
Whether the search part of the fetch method (so dealing with alt names was already executed or not.
Definition: DataObjectHandleBase.h:90
GaudiException
Definition: GaudiException.h:31
DataObjectHandleBase::DataObjectHandleBase
DataObjectHandleBase(const DataObjID &k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
Definition: DataObjectHandleBase.cpp:55
DataObjectHandleBase::m_optional
bool m_optional
Definition: DataObjectHandleBase.h:81
Gaudi::DataHandle::setKey
virtual void setKey(DataObjID key) const
Definition: DataHandle.h:57
INamedInterface::name
virtual const std::string & name() const =0
Retrieve the name of the instance.
DataObjectHandleBase::operator=
DataObjectHandleBase & operator=(const DataObjectHandleBase &)
Definition: DataObjectHandleBase.cpp:39
IDataProviderSvc.h
DataObjectHandleBase::isOptional
bool isOptional() const
Check if the data object declared is optional for the algorithm.
Definition: DataObjectHandleBase.h:59
IDataHandleHolder::declare
virtual void declare(Gaudi::DataHandle &)=0
DataObjectHandleBase::setRead
void setRead(bool wasRead=true)
Definition: DataObjectHandleBase.h:69
bug_34121.tool
tool
Definition: bug_34121.py:17
TimingHistograms.name
name
Definition: TimingHistograms.py:23
StatusCode
Definition: StatusCode.h:65
Gaudi::DataHandle::owner
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:53
DataObjectHandleBase::m_init
bool m_init
Definition: DataObjectHandleBase.h:80
std::cerr
LIKELY
#define LIKELY(x)
Definition: Kernel.h:105
Gaudi::Algorithm
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:90
DataObjectHandleBase
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
Definition: DataObjectHandleBase.h:35
IDataHandleHolder::renounce
virtual void renounce(Gaudi::DataHandle &)=0
Algorithm.h
Gaudi::DataHandle::objKey
virtual const std::string & objKey() const
Definition: DataHandle.h:60
Gaudi::DataHandle::m_owner
IDataHandleHolder * m_owner
Definition: DataHandle.h:81
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
MsgStream
Definition: MsgStream.h:34
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:221
DataObjID
Definition: DataObjID.h:47
DataObjectHandleBase::fetch
DataObject * fetch() const
Definition: DataObjectHandleBase.cpp:69
Gaudi::DataHandle::Mode
Mode
Definition: DataHandle.h:40
StatusCode::ignore
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition: StatusCode.h:156
std::endl
T endl(T... args)
Gaudi::Algorithm::evtSvc
SmartIF< IDataProviderSvc > & evtSvc() const
shortcut for method eventSvc
Definition: Algorithm.h:248
AlgTool
Definition: AlgTool.h:62
ServiceLocatorHelper.h
Gaudi::DataHandle::mode
virtual Mode mode() const
Definition: DataHandle.h:55
std
STL namespace.
DataObjectHandleBase.h
DataObject
Definition: DataObject.h:40
AlgTool.h
DataObjectHandleBase::setWritten
void setWritten(bool wasWritten=true)
Definition: DataObjectHandleBase.h:70
SerializeSTL.h
DataObjectHandleBase::~DataObjectHandleBase
virtual ~DataObjectHandleBase()
Definition: DataObjectHandleBase.cpp:66
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
INVALID_DATAOBJID
const DataObjID INVALID_DATAOBJID
Definition: DataObjectHandleBase.cpp:23
DataObjectHandleBase::isValid
bool isValid() const
Definition: DataObjectHandleBase.cpp:148
DataObjectHandleBase::m_searchMutex
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...
Definition: DataObjectHandleBase.h:96
Gaudi::DataHandle::fullKey
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:61
DataObjectHandleBase::m_wasRead
bool m_wasRead
Definition: DataObjectHandleBase.h:82
DataObjectHandleBase::init
bool init() override
Definition: DataObjectHandleBase.cpp:119