ATLAS Offline Software
Loading...
Searching...
No Matches
EventSelectorAthenaPoolSharedIO.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
9
12
15
16// Framework
17#include "GaudiKernel/FileIncident.h"
18#include "GaudiKernel/IIncidentSvc.h"
19#include "GaudiKernel/StatusCode.h"
21
22// Pool
24
25namespace {
27 StatusCode putEvent_ST(const IAthenaIPCTool& tool,
28 long eventNumber, const void* source,
29 size_t nbytes, unsigned int status) {
30 StatusCode sc ATLAS_THREAD_SAFE = tool.putEvent(eventNumber, source, nbytes, status);
31 return sc;
32 }
33}
34
35//________________________________________________________________________________
36EventSelectorAthenaPoolSharedIO::EventSelectorAthenaPoolSharedIO(const std::string& name, ISvcLocator* pSvcLocator) :
37 base_class(name, pSvcLocator) {
38}
39//________________________________________________________________________________
41 if (!EventSelectorAthenaPool::initialize().isSuccess()) {
42 return StatusCode::FAILURE;
43 }
44 // Get SharedMemoryTool (if configured)
45 if (!m_eventStreamingTool.empty() && !m_eventStreamingTool.retrieve().isSuccess()) {
46 ATH_MSG_FATAL("Cannot get " << m_eventStreamingTool.typeAndName() << "");
47 return StatusCode::FAILURE;
48 } else if (m_makeStreamingToolClient.value() == -1) {
49 std::string dummyStr;
50 ATH_CHECK(m_eventStreamingTool->makeClient(m_makeStreamingToolClient.value(), dummyStr));
51 }
52 // Don't listen to the Event Processing incidents
53 if (!m_eventStreamingTool.empty()) {
54 m_incidentSvc->removeListener(this, IncidentType::BeginProcessing);
55 m_incidentSvc->removeListener(this, IncidentType::EndProcessing);
56 }
57 return StatusCode::SUCCESS;
58}
59//________________________________________________________________________________
61 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
62 return StatusCode::SUCCESS;
63 }
65}
66//________________________________________________________________________________
68 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
69 return StatusCode::SUCCESS;
70 }
72}
73
74//________________________________________________________________________________
76 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
77 delete m_endIter; m_endIter = nullptr;
78 return ::AthService::finalize();
79 }
81}
82
83//__________________________________________________________________________
85 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
86 m_guid = Guid::null();
87 m_evtCount = 0;
88 }
90}
91
92//________________________________________________________________________________
93StatusCode EventSelectorAthenaPoolSharedIO::next(IEvtSelector::Context& ctxt) const {
94 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
95 if (m_makeStreamingToolClient.value() == -1) {
96 StatusCode sc = m_eventStreamingTool->lockEvent(m_evtCount);
97 while (sc.isRecoverable()) {
98 usleep(1000);
99 sc = m_eventStreamingTool->lockEvent(m_evtCount);
100 }
101 }
102 // Increase event count
103 ++m_evtCount;
104 void* tokenStrPtr = nullptr;
105 unsigned int status = 0;
106 StatusCode sc = m_eventStreamingTool->getLockedEvent(&tokenStrPtr, status);
107 std::unique_ptr<const char[]> tokenStr{static_cast<const char*>(tokenStrPtr)};
108 if (sc.isRecoverable()) {
109 // Return end iterator
110 ctxt = *m_endIter;
111 // This is not a real failure but a Gaudi way of handling "end of job"
112 return StatusCode::FAILURE;
113 }
114 if (sc.isFailure()) {
115 ATH_MSG_FATAL("Cannot get NextEvent from AthenaSharedMemoryTool");
116 return StatusCode::FAILURE;
117 }
118 if (!eventStore()->clearStore().isSuccess()) {
119 ATH_MSG_WARNING("Cannot clear Store");
120 }
121 std::unique_ptr<AthenaAttributeList> athAttrList = std::make_unique<AthenaAttributeList>();
122 athAttrList->extend("eventRef", "string");
123 (*athAttrList)["eventRef"].data<std::string>() = tokenStr.get();
124 SG::WriteHandle<AthenaAttributeList> wh(m_attrListKey, eventStore()->name());
125 if (!wh.record(std::move(athAttrList)).isSuccess()) {
126 ATH_MSG_ERROR("Cannot record AttributeList to StoreGate " << StoreID::storeName(eventStore()->storeID()));
127 return StatusCode::FAILURE;
128 }
129 Token token;
130 token.fromString(tokenStr.get());
131 Guid guid = token.dbID();
132 if (guid != m_guid && m_processMetadata.value()) {
133 InputFileIncidentGuard::transition(m_inputFileGuard, *m_incidentSvc, name(),
134 "FID:" + guid.toString(), guid.toString(),
135 /*endFileName=*/{});
136 m_guid = guid;
137 }
138 return StatusCode::SUCCESS;
139 }
141}
142//________________________________________________________________________________
143StatusCode EventSelectorAthenaPoolSharedIO::next(IEvtSelector::Context& ctxt, int jump) const {
144 if (jump > 0) {
145 for (int i = 0; i < jump; i++) {
146 ATH_CHECK(next(ctxt));
147 }
148 return StatusCode::SUCCESS;
149 }
150 return StatusCode::FAILURE;
151}
152//________________________________________________________________________________
154 IDataShare* ds = dynamic_cast<IDataShare*>(m_athenaPoolCnvSvc.get());
155 if (ds == nullptr) {
156 ATH_MSG_ERROR("Cannot cast AthenaPoolCnvSvc to DataShare");
157 return StatusCode::FAILURE;
158 }
159 if (num < 0) {
160 if (ds->makeServer(num - 1).isFailure()) {
161 ATH_MSG_ERROR("Failed to switch AthenaPoolCnvSvc to output DataStreaming server");
162 }
163 return StatusCode::SUCCESS;
164 }
165 if (ds->makeServer(num + 1).isFailure()) {
166 ATH_MSG_ERROR("Failed to switch AthenaPoolCnvSvc to input DataStreaming server");
167 return StatusCode::FAILURE;
168 }
169 if (m_eventStreamingTool.empty()) {
170 return StatusCode::SUCCESS;
171 }
172 m_processMetadata = false;
173 ATH_MSG_DEBUG("makeServer: " << m_eventStreamingTool << " = " << num);
174 return(m_eventStreamingTool->makeServer(1, ""));
175}
176
177//________________________________________________________________________________
179 IDataShare* ds = dynamic_cast<IDataShare*>(m_athenaPoolCnvSvc.get());
180 if (ds == nullptr) {
181 ATH_MSG_ERROR("Cannot cast AthenaPoolCnvSvc to DataShare");
182 return StatusCode::FAILURE;
183 }
184 if (ds->makeClient(num + 1).isFailure()) {
185 ATH_MSG_ERROR("Failed to switch AthenaPoolCnvSvc to DataStreaming client");
186 return StatusCode::FAILURE;
187 }
188 if (m_eventStreamingTool.empty()) {
189 return StatusCode::SUCCESS;
190 }
191 ATH_MSG_DEBUG("makeClient: " << m_eventStreamingTool << " = " << num);
192 std::string dummyStr;
193 return(m_eventStreamingTool->makeClient(0, dummyStr));
194}
195
196//________________________________________________________________________________
198 IDataShare* ds = dynamic_cast<IDataShare*>(m_athenaPoolCnvSvc.get());
199 if (ds == nullptr) {
200 ATH_MSG_ERROR("Cannot cast AthenaPoolCnvSvc to DataShare");
201 return StatusCode::FAILURE;
202 }
203 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
204 StatusCode sc = m_eventStreamingTool->lockEvent(evtnum);
205 while (sc.isRecoverable()) {
206 usleep(1000);
207 sc = m_eventStreamingTool->lockEvent(evtnum);
208 }
209// Send stop client and wait for restart
210 if (sc.isFailure()) {
211 if (ds->makeClient(0).isFailure()) {
212 return StatusCode::FAILURE;
213 }
214 sc = m_eventStreamingTool->lockEvent(evtnum);
215 while (sc.isRecoverable() || sc.isFailure()) {
216 usleep(1000);
217 sc = m_eventStreamingTool->lockEvent(evtnum);
218 }
219//FIXME
220 if (ds->makeClient(1).isFailure()) {
221 return StatusCode::FAILURE;
222 }
223 }
224 return(sc);
225 }
226 return StatusCode::FAILURE;
227}
228
229//________________________________________________________________________________
231 IDataShare* ds = dynamic_cast<IDataShare*>(m_athenaPoolCnvSvc.get());
232 if (ds == nullptr) {
233 ATH_MSG_ERROR("Cannot cast AthenaPoolCnvSvc to DataShare");
234 return StatusCode::FAILURE;
235 }
236 if (m_eventStreamingTool.empty()) {
237 ATH_MSG_ERROR("No AthenaSharedMemoryTool configured for readEvent()");
238 return StatusCode::FAILURE;
239 }
240 ATH_MSG_VERBOSE("Called read Event " << maxevt);
241 std::unique_ptr<IEvtSelector::Context> ctxt = std::make_unique<EventContextAthenaPool>(this);
242 for (int i = 0; i < maxevt || maxevt == -1; ++i) {
243 if (!next(*ctxt).isSuccess()) {
244 if (m_evtCount == -1) {
245 ATH_MSG_VERBOSE("Called read Event and read last event from input: " << i);
246 break;
247 }
248 ATH_MSG_ERROR("Cannot read Event " << m_evtCount - 1 << " into AthenaSharedMemoryTool");
249 return StatusCode::FAILURE;
250 } else {
251 ATH_MSG_VERBOSE("Called next, read Event " << m_evtCount - 1);
252 }
253 }
254 ctxt.reset();
255 // End of file, wait for last event to be taken
256 StatusCode sc;
257 while ( (sc = putEvent_ST(*m_eventStreamingTool, 0, 0, 0, 0)).isRecoverable() ) {
258 while (ds->readData().isSuccess()) {
259 ATH_MSG_VERBOSE("Called last readData, while marking last event in readEvent()");
260 }
261 usleep(1000);
262 }
263 if (!sc.isSuccess()) {
264 ATH_MSG_ERROR("Cannot put last Event marker to AthenaSharedMemoryTool");
265 return StatusCode::FAILURE;
266 } else {
267 sc = ds->readData();
268 while (sc.isSuccess() || sc.isRecoverable()) {
269 sc = ds->readData();
270 }
271 ATH_MSG_DEBUG("Failed last readData -> Clients are stopped, after marking last event in readEvent()");
272 }
273 return StatusCode::SUCCESS;
274}
275//__________________________________________________________________________
277 if (!m_eventStreamingTool.empty()) {
278 if (m_eventStreamingTool->isServer()) {
279 IDataShare* ds = dynamic_cast<IDataShare*>(m_athenaPoolCnvSvc.get());
280 if (ds == nullptr) {
281 ATH_MSG_ERROR("Cannot cast AthenaPoolCnvSvc to DataShare");
282 return StatusCode::FAILURE;
283 }
284 std::string token = m_headerIterator->eventRef().toString();
285 StatusCode sc;
286 while ( (sc = putEvent_ST(*m_eventStreamingTool,
287 m_evtCount - 1, token.c_str(),
288 token.length() + 1, 0)).isRecoverable() ) {
289 while (ds->readData().isSuccess()) {
290 ATH_MSG_VERBOSE("Called last readData, while putting next event in next()");
291 }
292 // Nothing to do right now, trigger alternative (e.g. caching) here? Currently just fast loop.
293 }
294 if (!sc.isSuccess()) {
295 ATH_MSG_ERROR("Cannot put Event " << m_evtCount - 1 << " to AthenaSharedMemoryTool");
296 return StatusCode::FAILURE;
297 }
298 } else {
299 return StatusCode::SUCCESS;
300 }
301 } else {
303 }
304 return StatusCode::SUCCESS;
305}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_FATAL(x,...)
This file contains the class definition for the EventContextAthenaPool class.
This file contains the class definition for the EventSelectorAthenaPoolSharedIO class.
static Double_t sc
This file contains the class definition for the Token class (migrated from POOL).
#define ATLAS_THREAD_SAFE
virtual StatusCode next(IEvtSelector::Context &ctxt) const override
Gaudi::Property< int > m_makeStreamingToolClient
Make this instance a Streaming Client during first iteration automatically.
virtual StatusCode makeServer(int num) override
Make this a server.
virtual StatusCode makeClient(int num) override
Make this a client.
EventSelectorAthenaPoolSharedIO(const std::string &name, ISvcLocator *pSvcLocator)
Standard Service Constructor.
virtual StatusCode initialize() override
Required of all Gaudi Services.
virtual StatusCode share(int evtnum) override
Request to share a given event number.
virtual StatusCode readEvent(int maxevt) override
Read the next maxevt events.
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
virtual StatusCode recordAttributeList() const override
Record AttributeList in StoreGate.
ToolHandle< IAthenaIPCTool > m_eventStreamingTool
virtual StatusCode start() override
virtual StatusCode initialize() override
Required of all Gaudi Services.
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
virtual StatusCode stop() override
virtual StatusCode next(IEvtSelector::Context &ctxt) const override
virtual StatusCode finalize() override
virtual StatusCode recordAttributeList() const override
Record AttributeList in StoreGate.
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition Guid.h:25
static const Guid & null() noexcept
NULL-Guid: static class method.
Definition Guid.cxx:14
Abstract interface for sharing data.
Definition IDataShare.h:24
static void transition(std::optional< InputFileIncidentGuard > &guard, IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Replace the guard in an optional, with strict End-before-Begin ordering.
static const std::string & storeName(const StoreID::type &s)
Definition StoreID.cxx:77
This class provides a token that identifies in a unique way objects on the persistent storage.
Definition Token.h:22
Token & fromString(const std::string_view from)
Build from the string representation of a token.
Definition Token.cxx:169
const Guid & dbID() const
Access database identifier.
Definition Token.h:65
::StatusCode StatusCode
StatusCode definition for legacy code.