18 #ifndef CSLIBGUARDED_RCU_GUARDED_H
19 #define CSLIBGUARDED_RCU_GUARDED_H
42 template <
typename... Us>
43 rcu_guarded(Us &&... data);
46 [[nodiscard]] write_handle lock_write();
49 [[nodiscard]] read_handle lock_read()
const;
55 using element_type = T;
59 write_handle(
const write_handle &other) =
delete;
60 write_handle &operator=(
const write_handle &other) =
delete;
62 write_handle(write_handle &&other) {
64 m_guard = std::move(other.m_guard);
65 m_accessed = other.m_accessed;
67 other.m_ptr =
nullptr;
68 other.m_accessed =
false;
71 write_handle &operator=(write_handle &&other) {
74 m_guard.rcu_write_unlock(*m_ptr);
78 m_guard = std::move(other.m_guard);
79 m_accessed = other.m_accessed;
81 other.m_ptr =
nullptr;
82 other.m_accessed =
false;
88 m_guard.rcu_write_unlock(*m_ptr);
92 T &operator*()
const {
97 T *operator->()
const {
103 void access()
const {
105 m_guard.rcu_write_lock(*m_ptr);
111 mutable typename T::rcu_write_guard m_guard;
112 mutable bool m_accessed;
118 using pointer =
const T *;
119 using element_type =
const T;
121 read_handle(
const T *ptr)
122 : m_ptr(ptr), m_accessed(
false)
126 read_handle(
const read_handle &other) =
delete;
127 read_handle &operator=(
const read_handle &other) =
delete;
129 read_handle(read_handle &&other) {
131 m_guard = std::move(other.m_guard);
132 m_accessed = other.m_accessed;
134 other.m_ptr =
nullptr;
135 other.m_accessed =
false;
138 read_handle &operator=(read_handle &&other) {
141 m_guard.rcu_read_unlock(*m_ptr);
145 m_guard = std::move(other.m_guard);
146 m_accessed = other.m_accessed;
148 other.m_ptr =
nullptr;
149 other.m_accessed =
false;
155 m_guard.rcu_read_unlock(*m_ptr);
159 const T &operator*()
const {
164 const T *operator->()
const {
170 void access()
const {
172 m_guard.rcu_read_lock(*m_ptr);
178 mutable typename T::rcu_read_guard m_guard;
179 mutable bool m_accessed;
186 template <
typename T>
187 template <
typename... Us>
188 rcu_guarded<T>::rcu_guarded(Us &&... data)
189 : m_obj(std::forward<Us>(data)...)
193 template <
typename T>
194 auto rcu_guarded<T>::lock_write() -> write_handle
196 return write_handle(&m_obj);
199 template <
typename T>
200 auto rcu_guarded<T>::lock_read()
const -> read_handle
202 return read_handle(&m_obj);
205 template <
typename T>
206 rcu_guarded<T>::write_handle::write_handle(T *ptr)
207 : m_ptr(ptr), m_accessed(
false)