qxLib
threads_shared.h
Go to the documentation of this file.
1 /**
2 
3  @file threads_shared.h
4  @author Khrapov
5  @date 4.03.2021
6  @copyright © Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 #pragma once
10 
12 
13 #include <mutex>
14 #include <optional>
15 
16 namespace qx
17 {
18 
19 template<class data_t, class synchronization_primitive_t>
20 class threads_shared;
21 
22 /**
23 
24  @class shared_proxy
25  @brief A proxy class that provides access to an object stored in
26  threads_shared and provides raii for synchronization primitives
27  @details Locks synchronization primitive in constructor and unlocks in destructor
28  @tparam data_t - data type
29  @tparam synchronization_primitive_t - synchronization primitive type
30  @author Khrapov
31  @date 4.03.2021
32 
33 **/
34 template<class data_t, class synchronization_primitive_t>
36 {
38 
39 private:
40  /**
41  @brief shared_proxy object constructor
42  @param pData - pointer to the protected data
43  @param pSynchronizationPrimitive - pointer to the synchronization primitive
44  @param bTryLock - if true, function won't wait for other
45  threads to unlock the sp and will construct
46  shared_proxy with nullptrs
47  **/
48  shared_proxy(data_t* pData, synchronization_primitive_t* pSynchronizationPrimitive, bool bTryLock);
49 
50 public:
51  QX_NONCOPYABLE(shared_proxy);
52 
53  shared_proxy(shared_proxy&& other) noexcept;
54  shared_proxy& operator=(shared_proxy&& other) noexcept;
55 
56  ~shared_proxy();
57 
58  [[nodiscard]] data_t* operator->() noexcept;
59  [[nodiscard]] const data_t* operator->() const noexcept;
60 
61  [[nodiscard]] data_t& operator*() noexcept;
62  [[nodiscard]] const data_t& operator*() const noexcept;
63 
64 private:
65  synchronization_primitive_t* m_pSynchronizationPrimitive = nullptr;
66  data_t* m_pData = nullptr;
67 };
68 
69 /**
70 
71  @class threads_shared
72  @brief A class that provides thread-safe access to an object,
73  including construction and destruction
74  @tparam data_t - data type
75  @tparam synchronization_primitive_t - synchronization primitive type
76  @author Khrapov
77  @date 20.08.2021
78 
79 **/
80 template<class data_t, class synchronization_primitive_t = std::mutex>
82 {
83  /**
84 
85  @class synchronization_primitive_raii
86  @brief class guaranties thread safe construction and destruction of threads_shared
87  @author Khrapov
88  @date 20.08.2021
89 
90  **/
91  class synchronization_primitive_raii
92  {
93  public:
94  synchronization_primitive_raii();
95  ~synchronization_primitive_raii();
96 
97  /**
98  @brief Get synchronization primitive stored in proxy
99  @retval - synchronization primitive
100  **/
101  synchronization_primitive_t* get_object() noexcept;
102 
103  private:
104  synchronization_primitive_t sp;
105  };
106 
107 public:
109 
110  QX_NONCOPYMOVABLE(threads_shared);
111 
112  /**
113  @brief threads_shared object constructor
114  @tparam args_t - template parameter pack type
115  @param args - arguments to constructing Data object
116  **/
117  template<class... args_t>
118  threads_shared(args_t&&... args);
119 
120  /**
121  @brief threads_shared object destructor
122  **/
123  ~threads_shared();
124 
125  /**
126  @brief Wait for other threads to finish work with data object and retrieve
127  proxy object
128  @retval - proxy that provides access to an object stored in threads_shared
129  and provides raii for synchronization primitives
130  **/
131  [[nodiscard]] proxy lock();
132 
133  /**
134  @brief Try to lock synchronization primitive and get proxy
135  @retval - proxy that provides access to an object stored
136  in threads_shared or std::nullopt
137  **/
138  [[nodiscard]] std::optional<proxy> try_lock();
139 
140 private:
141  synchronization_primitive_raii m_SynchronizationPrimitiveRAII;
142  data_t m_Data;
143 };
144 
145 template<class synchronization_primitive_t>
146 inline void lock_synchronization_primitive(synchronization_primitive_t* pSP)
147 {
148  pSP->lock();
149 }
150 
151 template<class synchronization_primitive_t>
152 inline void unlock_synchronization_primitive(synchronization_primitive_t* pSP)
153 {
154  pSP->unlock();
155 }
156 
157 template<class synchronization_primitive_t>
158 inline bool try_lock_synchronization_primitive(synchronization_primitive_t* pSP)
159 {
160  return pSP->try_lock();
161 }
162 
163 } // namespace qx
164 
A proxy class that provides access to an object stored in threads_shared and provides raii for synchr...
A class that provides thread-safe access to an object, including construction and destruction.
proxy lock()
Wait for other threads to finish work with data object and retrieve proxy object.
std::optional< proxy > try_lock()
Try to lock synchronization primitive and get proxy.
threads_shared(args_t &&... args)
threads_shared object constructor
~threads_shared()
threads_shared object destructor