di 0.1.0
Loading...
Searching...
No Matches
unique_lock.h
Go to the documentation of this file.
1#pragma once
2
5#include "di/util/exchange.h"
6#include "di/util/swap.h"
7
8namespace di::sync {
9struct DeferLock {};
10struct TryToLock {};
11struct AdoptLock {};
12
13constexpr inline auto defer_lock = DeferLock {};
14constexpr inline auto try_to_lock = TryToLock {};
15constexpr inline auto adopt_lock = AdoptLock {};
16
17template<concepts::Lock Lock>
19public:
20 UniqueLock() = default;
21 constexpr UniqueLock(UniqueLock&& other)
22 : m_mutex(di::exchange(other.m_mutex, nullptr)), m_owned(di::exchange(other.m_owned, false)) {}
23
24 constexpr explicit UniqueLock(Lock& mutex) : m_mutex(&mutex) { lock(); }
25
26 constexpr UniqueLock(Lock& mutex, DeferLock) : m_mutex(&mutex) {}
27 constexpr UniqueLock(Lock& mutex, TryToLock) : m_mutex(&mutex) { try_lock(); }
28 constexpr UniqueLock(Lock& mutex, AdoptLock) : m_mutex(&mutex), m_owned(true) {}
29
30 constexpr ~UniqueLock() {
31 if (m_owned && m_mutex) {
32 unlock();
33 }
34 }
35
36 constexpr auto operator=(UniqueLock&& other) -> UniqueLock& {
37 if (m_owned && m_mutex) {
38 unlock();
39 }
40 m_mutex = di::exchange(other.m_mutex, nullptr);
41 m_owned = di::exchange(other.m_owned, false);
42 return *this;
43 }
44
45 constexpr void lock() {
46 DI_ASSERT(m_mutex);
47 DI_ASSERT(!m_owned);
48 m_mutex->lock();
49 m_owned = true;
50 }
51
52 constexpr auto try_lock() -> bool {
53 DI_ASSERT(m_mutex);
54 DI_ASSERT(!m_owned);
55 m_owned = m_mutex->try_lock();
56 return m_owned;
57 }
58
59 constexpr void unlock() {
60 DI_ASSERT(m_mutex);
61 DI_ASSERT(m_owned);
62 m_mutex->unlock();
63 m_owned = false;
64 }
65
66 constexpr void swap(UniqueLock& other) {
67 di::swap(m_mutex, other.m_mutex);
68 di::swap(m_owned, other.m_owned);
69 }
70
71 constexpr auto release() -> Lock* {
72 auto result = di::exchange(m_mutex, nullptr);
73 m_owned = false;
74 return result;
75 }
76
77 constexpr auto mutex() const -> Lock* { return m_mutex; }
78
79 constexpr auto owns_lock() const -> bool { return bool(m_mutex) && m_owned; }
80 constexpr explicit operator bool() const { return owns_lock(); }
81
82private:
83 Lock* m_mutex { nullptr };
84 bool m_owned { false };
85};
86}
87
88namespace di {
89using sync::AdoptLock;
90using sync::DeferLock;
91using sync::TryToLock;
93
97}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition unique_lock.h:18
constexpr UniqueLock(Lock &mutex, TryToLock)
Definition unique_lock.h:27
constexpr UniqueLock(Lock &mutex, AdoptLock)
Definition unique_lock.h:28
constexpr auto release() -> Lock *
Definition unique_lock.h:71
constexpr void lock()
Definition unique_lock.h:45
constexpr UniqueLock(Lock &mutex)
Definition unique_lock.h:24
constexpr ~UniqueLock()
Definition unique_lock.h:30
constexpr UniqueLock(UniqueLock &&other)
Definition unique_lock.h:21
constexpr auto operator=(UniqueLock &&other) -> UniqueLock &
Definition unique_lock.h:36
constexpr void unlock()
Definition unique_lock.h:59
constexpr void swap(UniqueLock &other)
Definition unique_lock.h:66
constexpr auto try_lock() -> bool
Definition unique_lock.h:52
constexpr UniqueLock(Lock &mutex, DeferLock)
Definition unique_lock.h:26
constexpr auto owns_lock() const -> bool
Definition unique_lock.h:79
constexpr auto mutex() const -> Lock *
Definition unique_lock.h:77
Definition atomic.h:12
constexpr auto try_to_lock
Definition unique_lock.h:14
constexpr auto defer_lock
Definition unique_lock.h:13
constexpr auto adopt_lock
Definition unique_lock.h:15
Definition any_storable.h:9
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
constexpr struct di::util::SwapFunction swap
Definition unique_lock.h:11
Definition unique_lock.h:9
Definition unique_lock.h:10