ATLAS Offline Software
SimpleUpdater.icc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
3  */
4 /**
5  * @file CxxUtils/SimpleUpdater.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Dec, 2020
8  * @brief Simple (non-deleting) Updater implementation.
9  */
10 
11 
12 namespace CxxUtils {
13 
14 
15 /**
16  * @brief Move constructor.
17  */
18 template <class T>
19 SimpleUpdater<T>::SimpleUpdater (SimpleUpdater&& other)
20  : m_obj (static_cast<const T*> (other.m_obj)),
21  m_objs (std::move (other.m_objs))
22 {
23 }
24 
25 
26 /**
27  * @brief Return a reference to the current object.
28  */
29 template <class T>
30 inline
31 const T& SimpleUpdater<T>::get() const
32 {
33  return *m_obj;
34 }
35 
36 
37 /**
38  * @brief Install a new object.
39  * @param p The new object to install.
40  * @param ctx Current execution context.
41  *
42  * The existing object should not be deleted until it can no longer
43  * be referenced by any thread.
44  */
45 template <class T>
46 void SimpleUpdater<T>::update (std::unique_ptr<T> p, const Context_t&)
47 {
48  m_objs.push_back (std::move (p));
49  m_obj = m_objs.back().get();
50 }
51 
52 
53 /**
54  * @brief Queue an object for later deletion.
55  * @param p The object to delete.
56  *
57  * The object @c p will be queued for deletion once a grace period
58  * has passed for all slots. In contrast to using @c update,
59  * this does not change the current object.
60  */
61 template <class T>
62 void SimpleUpdater<T>::discard (std::unique_ptr<T> p)
63 {
64  m_objs.push_back (std::move (p));
65 }
66 
67 
68 /**
69  * @brief Mark that an event slot is not referencing this object.
70  *
71  * A no-op for @c SimpleUpdater.
72  */
73 template <class T>
74 void SimpleUpdater<T>::quiescent (const Context_t&)
75 {
76 }
77 
78 
79 /**
80  * @brief Delete all objects we're managing except for the current one.
81  *
82  * This is NOT concurrency-safe. No other threads may be accessing
83  * the objects managed here.
84  */
85 template <class T>
86 void SimpleUpdater<T>::clean()
87 {
88  const T* obj = m_obj;
89  auto it = std::remove_if (m_objs.begin(), m_objs.end(),
90  [&] (const std::unique_ptr<T>& p) { return p.get() != obj; });
91  m_objs.erase (it, m_objs.end());
92 }
93 
94 
95 /**
96  * @brief Swap this object with another.
97  * @param other The other object with which to swap.
98  *
99  * This operation is NOT concurrency-safe. No other threads may be accessing
100  * either container during this operation.
101  */
102 template <class T>
103 void SimpleUpdater<T>::swap (SimpleUpdater& other)
104 {
105  const T* tmp = m_obj.load (std::memory_order_relaxed);
106  m_obj.store (other.m_obj.load(std::memory_order_relaxed), std::memory_order_relaxed);
107  other.m_obj.store (tmp, std::memory_order_relaxed);
108 
109  m_objs.swap (other.m_objs);
110 }
111 
112 
113 /**
114  * @brief Return the current event context.
115  */
116 template <class T>
117 const typename SimpleUpdater<T>::Context_t SimpleUpdater<T>::defaultContext()
118 {
119  return Context_t();
120 }
121 
122 
123 } // namespace CxxUtils
124