libfilezilla
Loading...
Searching...
No Matches
mutex.hpp
Go to the documentation of this file.
1#ifndef LIBFILEZILLA_MUTEX_HEADER
2#define LIBFILEZILLA_MUTEX_HEADER
3
7#include "libfilezilla.hpp"
8#include "time.hpp"
9
10#ifdef FZ_WINDOWS
11#include "glue/windows.hpp"
12#else
13#include <pthread.h>
14#endif
15
16//#define LFZ_DEBUG_MUTEXES
17#ifdef LFZ_DEBUG_MUTEXES
18
19#include <memory>
20
21namespace fz {
22class mutex;
24struct FZ_PUBLIC_SYMBOL mutex_debug final
25{
26 mutex_debug(mutex* mtx)
27 : mtx_(mtx)
28 {}
29
30 static void record_lock(void* m);
31 static void record_unlock(void* m);
32
33 size_t count_{};
34 mutex* mtx_{};
35
36 std::vector<std::tuple<std::weak_ptr<mutex_debug>, std::vector<void*>>> order_;
37};
38}
39#endif
40
41namespace fz {
51class FZ_PUBLIC_SYMBOL mutex final
52{
53public:
54 explicit mutex(bool recursive = true);
55 ~mutex();
56
57 mutex(mutex const&) = delete;
58 mutex& operator=(mutex const&) = delete;
59
61 void lock();
62
64 void unlock();
65
67 bool try_lock();
68
69private:
70 friend class condition;
71 friend class scoped_lock;
72
73#ifdef FZ_WINDOWS
74 CRITICAL_SECTION m_;
75#else
76 pthread_mutex_t m_;
77#endif
78#ifdef LFZ_DEBUG_MUTEXES
79public:
80 std::shared_ptr<mutex_debug> h_;
81#endif
82};
83
92class FZ_PUBLIC_SYMBOL scoped_lock final
93{
94public:
95 explicit scoped_lock(mutex& m)
96 : m_(&m.m_)
97 {
98#ifdef FZ_WINDOWS
99 EnterCriticalSection(m_);
100#else
101 pthread_mutex_lock(m_);
102#endif
103#ifdef LFZ_DEBUG_MUTEXES
104 mutex_debug::record_lock(m_);
105#endif
106 }
107
109 {
110 if (locked_) {
111#ifdef LFZ_DEBUG_MUTEXES
112 mutex_debug::record_unlock(m_);
113#endif
114#ifdef FZ_WINDOWS
115 LeaveCriticalSection(m_);
116#else
117 pthread_mutex_unlock(m_);
118#endif
119 }
120
121 }
122
123 scoped_lock(scoped_lock const&) = delete;
124 scoped_lock& operator=(scoped_lock const&) = delete;
125
126 scoped_lock(scoped_lock && op) noexcept
127 {
128 m_ = op.m_;
129 op.m_ = 0;
130 locked_ = op.locked_;
131 op.locked_ = false;
132 }
133
134 scoped_lock& operator=(scoped_lock && op) noexcept
135 {
136 if (this != &op) {
137 m_ = op.m_;
138 op.m_ = 0;
139 locked_ = op.locked_;
140 op.locked_ = false;
141 }
142 return *this;
143 }
144
149 void lock()
150 {
151 locked_ = true;
152#ifdef FZ_WINDOWS
153 EnterCriticalSection(m_);
154#else
155 pthread_mutex_lock(m_);
156#endif
157#ifdef LFZ_DEBUG_MUTEXES
158 mutex_debug::record_lock(m_);
159#endif
160
161 }
162
167 void unlock()
168 {
169 locked_ = false;
170#ifdef LFZ_DEBUG_MUTEXES
171 mutex_debug::record_unlock(m_);
172#endif
173#ifdef FZ_WINDOWS
174 LeaveCriticalSection(m_);
175#else
176 pthread_mutex_unlock(m_);
177#endif
178 }
179
180private:
181 friend class condition;
182
183#ifdef FZ_WINDOWS
184 CRITICAL_SECTION * m_;
185#else
186 pthread_mutex_t * m_;
187#endif
188 bool locked_{true};
189};
190
195class FZ_PUBLIC_SYMBOL condition final
196{
197public:
198 condition();
199 ~condition();
200
201 condition(condition const&) = delete;
202 condition& operator=(condition const&) = delete;
203
211
223 bool wait(scoped_lock& l, duration const& timeout);
224
235
243 bool signalled(scoped_lock const&) const { return signalled_; }
244private:
245#ifdef FZ_WINDOWS
246 CONDITION_VARIABLE cond_;
247#else
248 pthread_cond_t cond_;
249#endif
250 bool signalled_{};
251};
252
253}
254#endif
Waitable condition variable.
Definition: mutex.hpp:196
void wait(scoped_lock &l)
Wait indefinitely for condition to become signalled.
bool wait(scoped_lock &l, duration const &timeout)
Wait until timeout for condition to become signalled.
bool signalled(scoped_lock const &) const
Check if condition is already signalled.
Definition: mutex.hpp:243
void signal(scoped_lock &l)
Signal condition variable.
The duration class represents a time interval in milliseconds.
Definition: time.hpp:291
Lean replacement for std::(recursive_)mutex.
Definition: mutex.hpp:52
void unlock()
Beware, manual locking isn't exception safe, use scoped_lock.
bool try_lock()
Beware, manual locking isn't exception safe.
void lock()
Beware, manual locking isn't exception safe, use scoped_lock.
A simple scoped lock.
Definition: mutex.hpp:93
void unlock()
Releases the mutex.
Definition: mutex.hpp:167
void lock()
Obtains the mutex.
Definition: mutex.hpp:149
Sets some global macros and further includes string.hpp.
The namespace used by libfilezilla.
Definition: apply.hpp:17
Assorted classes dealing with time.