Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v36r11 (bdb84f5f)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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_searchDone( other.m_searchDone.load() ) {
33  m_owner->declare( *this );
34 }
35 
36 //---------------------------------------------------------------------------
38  // avoid modification of searchDone in other while we are copying
39  auto guard = std::scoped_lock{ other.m_searchMutex };
40  // FIXME: operator= should not change our owner, only our 'value'
41  Gaudi::DataHandle::operator=( other );
42  m_EDS = other.m_EDS;
43  m_MS = other.m_MS;
44  m_init = other.m_init;
45  m_optional = other.m_optional;
46  m_searchDone = other.m_searchDone.load();
47  return *this;
48 }
49 
50 //---------------------------------------------------------------------------
52  : Gaudi::DataHandle( std::move( k ), a, owner ) {
53  m_owner->declare( *this );
54 }
55 
56 //---------------------------------------------------------------------------
57 
59  : DataObjectHandleBase( DataObjID{ std::move( k ) }, a, owner ) {}
60 
61 //---------------------------------------------------------------------------
63 
64 //---------------------------------------------------------------------------
66  DataObject* p = nullptr;
67  if ( m_searchDone ) { // fast path: searchDone, objKey is in its final state
68  m_EDS->retrieveObject( objKey(), p ).ignore();
69  return p;
70  }
71 
72  // slow path -- move into seperate function to improve code generation?
73 
74  // as m_searchDone is not true yet, objKey may change... so in this
75  // branch we _first_ grab the mutex, to avoid objKey changing while we use it
76 
77  // take a lock to be sure we only execute this one at a time
78  auto guard = std::scoped_lock{ m_searchMutex };
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  // note: if no seperator is found, this returns a range of one with the input as the single token
88  // so if the search was done while we were waiting on the mutex, this (also) does the right thing
89  auto tokens = boost::tokenizer<boost::char_separator<char>>{ objKey(), boost::char_separator<char>{ ":" } };
90  // let's try our alternatives (if any)
91  auto alt = std::find_if( tokens.begin(), tokens.end(),
92  [&]( const std::string& n ) { return m_EDS->retrieveObject( n, p ).isSuccess(); } );
93  if ( alt != tokens.end() && *alt != objKey() ) {
94  MsgStream log( m_MS, owner()->name() + ":DataObjectHandle" );
95  log << MSG::DEBUG << ": could not find \"" << objKey() << "\" -- using alternative source: \"" << *alt
96  << "\" instead" << endmsg;
97  // found something -- set it as default; this is not atomic, but
98  // at least in `fetch` there is no use of `objKey` that races with
99  // this assignment... (but there may be others!)
100  setKey( *alt ); // if there was one token, this is an unnecessary write... but who cares...
101  }
102 
103  bool expected = false; // but could be true (already)...
104  m_searchDone.compare_exchange_strong( expected, true ); // if not yet true, set it to true...
105  return p;
106 }
107 
108 //---------------------------------------------------------------------------
109 
111  if ( m_init ) return true; // initialization already done
112 
113  if ( !owner() ) return false;
114 
115  Gaudi::Algorithm* algorithm = dynamic_cast<Gaudi::Algorithm*>( owner() );
116  if ( algorithm ) {
117  // Fetch the event Data Service from the algorithm
118  m_EDS = algorithm->evtSvc();
119  m_MS = algorithm->msgSvc();
120  } else {
121  AlgTool* tool = dynamic_cast<AlgTool*>( owner() );
122  if ( tool ) {
123  m_EDS = tool->evtSvc();
124  m_MS = tool->msgSvc();
125  } else {
126  throw GaudiException( "owner is neither AlgTool nor Gaudi::Algorithm", "Invalid Cast", StatusCode::FAILURE );
127  }
128  }
129  m_init = true;
130  return true;
131 }
132 
133 //---------------------------------------------------------------------------
134 
136 
137 //---------------------------------------------------------------------------
138 
140 
141  str << d.fullKey() << " m: " << d.mode();
142  if ( d.owner() ) str << " o: " << d.owner()->name();
143  str << " opt: " << d.isOptional();
144  return str;
145 }
IDataHandleHolder
Definition: IDataHandleHolder.h:24
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
std::string
STL class.
Gaudi.Configuration.log
log
Definition: Configuration.py:28
std::move
T move(T... args)
DataObjectHandleBase::m_EDS
SmartIF< IDataProviderSvc > m_EDS
Definition: DataObjectHandleBase.h:70
DataObjectHandleBase::m_MS
SmartIF< IMessageSvc > m_MS
Definition: DataObjectHandleBase.h:71
operator<<
std::ostream & operator<<(std::ostream &str, const DataObjectHandleBase &d)
Definition: DataObjectHandleBase.cpp:139
std::find_if
T find_if(T... args)
GaudiException
Definition: GaudiException.h:31
DataObjectHandleBase::m_optional
bool m_optional
Definition: DataObjectHandleBase.h:74
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:37
std::atomic::compare_exchange_strong
T compare_exchange_strong(T... args)
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
bug_34121.tool
tool
Definition: bug_34121.py:17
TimingHistograms.name
name
Definition: TimingHistograms.py:25
Gaudi::DataHandle::owner
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:53
DataObjectHandleBase::m_init
bool m_init
Definition: DataObjectHandleBase.h:73
std::atomic::load
T load(T... args)
std::cerr
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:235
DataObjID
Definition: DataObjID.h:47
DataObjectHandleBase::fetch
DataObject * fetch() const
Definition: DataObjectHandleBase.cpp:65
Gaudi::DataHandle::Mode
Mode
Definition: DataHandle.h:40
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
DataObjectHandleBase::m_searchDone
std::atomic< bool > m_searchDone
Whether the search part of the fetch method (so dealing with alt names was already executed or not.
Definition: DataObjectHandleBase.h:81
std
STL namespace.
DataObjectHandleBase.h
DataObject
Definition: DataObject.h:40
DataObjectHandleBase::~DataObjectHandleBase
~DataObjectHandleBase() override
Definition: DataObjectHandleBase.cpp:62
AlgTool.h
DataObjectHandleBase::DataObjectHandleBase
DataObjectHandleBase(DataObjID k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
Definition: DataObjectHandleBase.cpp:51
SerializeSTL.h
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:135
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:87
Gaudi::DataHandle::fullKey
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:61
DataObjectHandleBase::init
bool init() override
Definition: DataObjectHandleBase.cpp:110