libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lock_holder.h
Go to the documentation of this file.
1
15#pragma once
16
17// clang-format off
18#include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
19// clang-format on
20#include <cstring>
21// clang-format off
22#include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
23// clang-format on
24
25#include <libcopp/utils/config/libcopp_build_features.h>
26
27LIBCOPP_COPP_NAMESPACE_BEGIN
28namespace util {
29namespace lock {
30namespace detail {
31template <typename TLock>
32struct LIBCOPP_COPP_API_HEAD_ONLY default_lock_action {
33 inline bool operator()(TLock &lock) const noexcept {
34 lock.lock();
35 return true;
36 } // namespace detail
37}; // namespace lock
38
39template <typename TLock>
40struct LIBCOPP_COPP_API_HEAD_ONLY default_try_lock_action {
41 inline bool operator()(TLock &lock) const noexcept { return lock.try_lock(); } // namespace util
42};
43
44template <typename TLock>
45struct LIBCOPP_COPP_API_HEAD_ONLY default_unlock_action {
46 inline void operator()(TLock &lock) const noexcept { lock.unlock(); }
47};
48
49template <typename TLock>
50struct LIBCOPP_COPP_API_HEAD_ONLY default_try_unlock_action {
51 inline bool operator()(TLock &lock) const noexcept { return lock.try_unlock(); }
52};
53
54template <typename TLock>
55struct LIBCOPP_COPP_API_HEAD_ONLY default_read_lock_action {
56 inline bool operator()(TLock &lock) const noexcept {
57 lock.read_lock();
58 return true;
59 }
60};
61
62template <typename TLock>
63struct LIBCOPP_COPP_API_HEAD_ONLY default_read_unlock_action {
64 inline void operator()(TLock &lock) const noexcept { lock.read_unlock(); }
65};
66
67template <typename TLock>
68struct LIBCOPP_COPP_API_HEAD_ONLY default_write_lock_action {
69 inline bool operator()(TLock &lock) const noexcept {
70 lock.write_lock();
71 return true;
72 }
73};
74
75template <typename TLock>
76struct LIBCOPP_COPP_API_HEAD_ONLY default_write_unlock_action {
77 inline void operator()(TLock &lock) const noexcept { lock.write_unlock(); }
78};
79} // namespace detail
80
81template <typename TLock, typename TLockAct = detail::default_lock_action<TLock>,
82 typename TUnlockAct = detail::default_unlock_action<TLock> >
83class LIBCOPP_COPP_API_HEAD_ONLY lock_holder {
84 public:
85 using value_type = TLock;
86
87 lock_holder(lock_holder &&other) : lock_flag_(other.lock_flag_) { other.lock_flag_ = nullptr; }
88
89 inline lock_holder &operator=(lock_holder &&other) noexcept {
90 if (&other == this) {
91 return *this;
92 }
93
94 if (lock_flag_ != other.lock_flag_) {
95 reset();
96 }
97
98 lock_flag_ = other.lock_flag_;
99 return *this;
100 }
101
102 inline lock_holder(TLock &lock) : lock_flag_(&lock) {
103 if (false == TLockAct()(lock)) {
104 lock_flag_ = nullptr;
105 }
106 }
107
109 if (nullptr != lock_flag_) {
110 TUnlockAct()(*lock_flag_);
111 }
112 }
113
114 inline bool is_available() const noexcept { return nullptr != lock_flag_; }
115
116 inline void reset() noexcept {
117 if (nullptr != lock_flag_) {
118 value_type *value = lock_flag_;
119 lock_flag_ = nullptr;
120 TUnlockAct()(*value);
121 }
122 }
123
124 private:
125 lock_holder(const lock_holder &) = delete;
127
128 private:
130};
131
132template <typename TLock>
133class LIBCOPP_COPP_API_HEAD_ONLY read_lock_holder
134 : public lock_holder<TLock, detail::default_read_lock_action<TLock>, detail::default_read_unlock_action<TLock> > {
135 public:
136 inline read_lock_holder(TLock &lock)
137 : lock_holder<TLock, detail::default_read_lock_action<TLock>, detail::default_read_unlock_action<TLock> >(lock) {}
138};
139
140template <typename TLock>
141class LIBCOPP_COPP_API_HEAD_ONLY write_lock_holder
142 : public lock_holder<TLock, detail::default_write_lock_action<TLock>, detail::default_write_unlock_action<TLock> > {
143 public:
144 inline write_lock_holder(TLock &lock)
145 : lock_holder<TLock, detail::default_write_lock_action<TLock>, detail::default_write_unlock_action<TLock> >(
146 lock) {}
147};
148} // namespace lock
149} // namespace util
150LIBCOPP_COPP_NAMESPACE_END
lock_holder(const lock_holder &)=delete
lock_holder(lock_holder &&other)
Definition lock_holder.h:87
bool is_available() const noexcept
lock_holder & operator=(lock_holder &&other) noexcept
Definition lock_holder.h:89
void reset() noexcept
lock_holder & operator=(const lock_holder &)=delete
bool operator()(TLock &lock) const noexcept
Definition lock_holder.h:33
bool operator()(TLock &lock) const noexcept
Definition lock_holder.h:56
void operator()(TLock &lock) const noexcept
Definition lock_holder.h:64
bool operator()(TLock &lock) const noexcept
Definition lock_holder.h:41
bool operator()(TLock &lock) const noexcept
Definition lock_holder.h:51
void operator()(TLock &lock) const noexcept
Definition lock_holder.h:46
bool operator()(TLock &lock) const noexcept
Definition lock_holder.h:69
void operator()(TLock &lock) const noexcept
Definition lock_holder.h:77