zpp
Zephyr C++20 Framework
unique_lock.hpp
Go to the documentation of this file.
1 
7 #ifndef ZPP_INCLUDE_ZPP_UNIQUE_LOCK_HPP
8 #define ZPP_INCLUDE_ZPP_UNIQUE_LOCK_HPP
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/__assert.h>
12 
13 #include <chrono>
14 
15 #include <zpp/result.hpp>
16 #include <zpp/error_code.hpp>
17 
18 namespace zpp {
19 
23 template<typename T_Mutex>
24 class unique_lock {
25 public:
26  using native_pointer = T_Mutex::native_pointer;
27  using native_const_pointer = T_Mutex::native_const_pointer;
28 public:
32  unique_lock() noexcept = default;
33 
37  explicit unique_lock(T_Mutex& lock) noexcept
38  : m_lock(&lock)
39  {
40  __ASSERT_NO_MSG(m_lock != nullptr);
41  auto res = m_lock->lock();
42  __ASSERT_NO_MSG(res != false);
43  m_is_owner = true;
44  }
45 
49  unique_lock(unique_lock&& src) noexcept
50  : m_lock(src.m_lock)
51  , m_is_owner(src.m_is_owner)
52  {
53  src.m_lock = nullptr;
54  src.m_is_owner = false;
55  }
56 
61  {
62  if (m_lock != nullptr && m_is_owner) {
63  auto res = m_lock->unlock();
64  __ASSERT_NO_MSG(res != false);
65  }
66 
67  m_lock = src.m_lock;
68  m_is_owner = src.m_is_owner;
69 
70  src.m_lock = nullptr;
71  src.m_is_owner = false;
72 
73  return *this;
74  }
75 
79  ~unique_lock() noexcept
80  {
81  if (m_lock != nullptr && m_is_owner) {
82  auto res = m_lock->unlock();
83  __ASSERT_NO_MSG(res != false);
84  }
85  }
86 
92  [[nodiscard]] auto lock() noexcept
93  {
95 
96  if (m_lock == nullptr) {
98  } else if (m_is_owner == true) {
100  } else {
101  res = m_lock->lock();
102  m_is_owner = (bool)res;
103  }
104 
105  return res;
106  }
107 
113  [[nodiscard]] auto try_lock() noexcept
114  {
116 
117  if (m_lock == nullptr) {
119  } else if (m_is_owner == true) {
121  } else {
122  res = m_lock->try_lock();
123  m_is_owner = (bool)res;
124  }
125 
126  return res;
127  }
128 
136  template<class T_Rep, class T_Period>
137  [[nodiscard]] auto
138  try_lock_for(const std::chrono::duration<T_Rep, T_Period>& timeout) noexcept
139  {
141 
142  if (m_lock == nullptr) {
144  } else if (m_is_owner == true) {
146  } else {
147  res = m_lock->try_lock_for(timeout);
148  m_is_owner = (bool)res;
149  }
150 
151  return res;
152  }
153 
157  [[nodiscard]] auto unlock() noexcept
158  {
160 
161  if (m_is_owner == false) {
163  } else if (m_lock == nullptr) {
165  } else {
166  res = m_lock->unlock();
167  m_is_owner = false;
168  }
169 
170  return res;
171  }
172 
176  constexpr T_Mutex* release() noexcept
177  {
178  auto ret = m_lock;
179  m_lock = nullptr;
180  m_is_owner = false;
181  return ret;
182  }
183 
187  constexpr bool owns_lock() const noexcept
188  {
189  return m_is_owner;
190  }
191 
195  explicit constexpr operator bool() const noexcept
196  {
197  return owns_lock();
198  }
199 
203  constexpr T_Mutex* mutex() const noexcept
204  {
205  return m_lock;
206  }
207 
213  constexpr auto native_handle() noexcept -> native_pointer
214  {
215  if (m_lock != nullptr)
216  return m_lock->native_handle();
217  else
218  return nullptr;
219  }
220 
226  constexpr auto native_handle() const noexcept -> native_const_pointer
227  {
228  if (m_lock != nullptr)
229  return m_lock->native_handle();
230  else
231  return nullptr;
232  }
233 private:
234  T_Mutex* m_lock{nullptr};
235  bool m_is_owner{false};
236 public:
237  unique_lock(const unique_lock&) = delete;
238  unique_lock& operator=(const unique_lock&) = delete;
239 };
240 
241 } // namespace zpp
242 
243 #endif // ZPP_INCLUDE_ZPP_UNIQUE_LOCK_HPP
result class
Definition: result.hpp:89
void assign_error(const T_Error &e) noexcept
Definition: result.hpp:219
zpp::unique_lock using zpp::mutex as a lock.
Definition: unique_lock.hpp:24
unique_lock() noexcept=default
Try locking the mutex without waiting.
auto lock() noexcept
Lock the mutex. Wait for ever until it is locked.
Definition: unique_lock.hpp:92
constexpr auto native_handle() const noexcept -> native_const_pointer
get the native zephyr mutex handle.
unique_lock(unique_lock &&src) noexcept
Try locking the mutex without waiting.
Definition: unique_lock.hpp:49
constexpr T_Mutex * mutex() const noexcept
Try locking the mutex without waiting.
auto try_lock_for(const std::chrono::duration< T_Rep, T_Period > &timeout) noexcept
Try locking the mutex with a timeout.
constexpr auto native_handle() noexcept -> native_pointer
get the native zephyr mutex handle.
unique_lock & operator=(const unique_lock &)=delete
unique_lock & operator=(unique_lock &&src) noexcept
Try locking the mutex without waiting.
Definition: unique_lock.hpp:60
T_Mutex::native_const_pointer native_const_pointer
Definition: unique_lock.hpp:27
auto unlock() noexcept
Unlock the mutex.
T_Mutex::native_pointer native_pointer
Definition: unique_lock.hpp:26
constexpr bool owns_lock() const noexcept
Try locking the mutex without waiting.
auto try_lock() noexcept
Try locking the mutex without waiting.
unique_lock(const unique_lock &)=delete
constexpr T_Mutex * release() noexcept
Try locking the mutex without waiting.
~unique_lock() noexcept
Try locking the mutex without waiting.
Definition: unique_lock.hpp:79
@ k_inval
Invalid argument.
@ k_deadlk
Resource deadlock avoided.
@ k_perm
Not owner.