ATLAS Offline Software
Loading...
Searching...
No Matches
G4RunToolEventQueue.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <stdexcept>
9#include <utility>
10
11std::size_t G4RunToolEventQueue::Size() const
12{
13 std::scoped_lock lock(m_mutex);
14 return m_events.size();
15}
16
18{
19 if (!event) {
20 throw std::invalid_argument(
21 "G4RunToolEventQueue::PushEvent requires a non-null event");
22 }
23
24 auto syncInterface = event->SyncInterface();
25 bool eventQueued = false;
26 {
27 std::scoped_lock lock(m_mutex);
28 if (!m_closed) {
32 [](const WeakSyncInterface& interface) {
33 return interface.expired();
34 }),
36 if (syncInterface) {
37 m_outstandingEvents.emplace_back(syncInterface);
38 }
39 m_events.push(std::move(event));
40 eventQueued = true;
41 }
42 }
43
44 if (eventQueued) {
45 m_cv.notify_one();
46 }
47 else if (syncInterface) {
48 // The event was never exposed to Geant4, so its owned state can be safely
49 // released before the Athena thread is notified.
50 event.reset();
51 syncInterface->Complete(
53 }
54}
55
57{
58 std::unique_lock lock(m_mutex);
59 m_cv.wait(lock, [this] { return m_closed || !m_events.empty(); });
60 if (m_closed) {
61 return nullptr;
62 }
63
64 UPEvent event = std::move(m_events.front());
65 m_events.pop();
66 return event;
67}
68
70{
71 {
72 std::scoped_lock lock(m_mutex);
73 m_closed = true;
74 }
75 m_cv.notify_all();
76}
77
79{
80 std::vector<WeakSyncInterface> outstandingEvents;
81 std::queue<UPEvent> abandonedEvents;
82 {
83 std::scoped_lock lock(m_mutex);
84 outstandingEvents.swap(m_outstandingEvents);
85 abandonedEvents.swap(m_events);
86 }
87
88 // Destroy queued event information before waking Athena. In-flight event
89 // information has already been destroyed as part of worker termination.
90 while (!abandonedEvents.empty()) {
91 abandonedEvents.pop();
92 }
93
94 for (const WeakSyncInterface& weakInterface : outstandingEvents) {
95 if (auto syncInterface = weakInterface.lock()) {
96 syncInterface->Complete(
98 }
99 }
100}
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
std::condition_variable m_cv
void PushEvent(UPEvent event)
Submit a non-null event. Throws std::invalid_argument for null events.
std::queue< UPEvent > m_events
std::weak_ptr< G4EventSynchronizationInterface > WeakSyncInterface
void CompleteOutstandingEvents() noexcept
Release abandoned events and report run termination to their waiters.
std::size_t Size() const
std::unique_ptr< AtlasG4SyncEventUserInfo > UPEvent
std::vector< WeakSyncInterface > m_outstandingEvents
void Close() noexcept
Stop accepting events and wake all Geant4 workers. Idempotent.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.