nlib
CriticalSection.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
4 #define INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
5 
6 #include "nn/nlib/Config.h"
7 #include "nn/nlib/Swap.h"
8 
9 NLIB_NAMESPACE_BEGIN
10 class TimeSpan;
11 class DateTime;
12 namespace threading {
13 
14 class NLIB_CAPABILITY("mutex") SimpleCriticalSection {
15  public:
16 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
17  constexpr SimpleCriticalSection() NLIB_NOEXCEPT = default;
18 #else
19  SimpleCriticalSection() NLIB_NOEXCEPT {
20  errno_t e = nlib_mutex_init(&mutex_);
21  NLIB_ASSERT_NOERR(e);
22  NLIB_UNUSED(e);
23  }
24 #endif
25  ~SimpleCriticalSection() NLIB_NOEXCEPT {
26  errno_t e = nlib_mutex_destroy(&mutex_);
27  NLIB_UNUSED(e);
28  NLIB_ASSERT_NOERR(e);
29  }
30  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
31  errno_t e = nlib_mutex_lock(&mutex_);
32  NLIB_UNUSED(e);
33  NLIB_ASSERT_NOERR(e);
34  }
35  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
36  errno_t e = nlib_mutex_unlock(&mutex_);
37  NLIB_UNUSED(e);
38  NLIB_ASSERT_NOERR(e);
39  }
40  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
41  errno_t e = nlib_mutex_trylock(&mutex_);
42  if (e == 0) return true;
43  NLIB_ASSERT(e == EBUSY);
44  return false;
45  }
47  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
48  return &mutex_;
49  }
50 
51  private:
52 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
54 #else
55  nlib_mutex mutex_;
56 #endif
57 };
58 
59 #ifndef NLIB_CRITICALSECTION_USE_FALLBACK
60 class NLIB_CAPABILITY("mutex") CriticalSection {
61  public:
62 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
63  constexpr CriticalSection() NLIB_NOEXCEPT = default;
64 #else
65  CriticalSection() NLIB_NOEXCEPT {
67  NLIB_ASSERT_NOERR(e);
68  NLIB_UNUSED(e);
69  }
70 #endif
71  ~CriticalSection() NLIB_NOEXCEPT { nlib_mutex_destroy(&mutex_); }
72  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
73  errno_t e = nlib_mutex_lock(&mutex_);
74  NLIB_ASSERT_NOERR(e);
75  NLIB_UNUSED(e);
76  }
77  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
78  errno_t e = nlib_mutex_unlock(&mutex_);
79  NLIB_ASSERT_NOERR(e);
80  NLIB_UNUSED(e);
81  }
82  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
83  errno_t e = nlib_mutex_trylock(&mutex_);
84  if (e == 0) return true;
85  NLIB_ASSERT(e == EBUSY);
86  return false;
87  }
89  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
90  return &mutex_;
91  }
92 
93  private:
94 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
96 #else
97  nlib_mutex mutex_;
98 #endif
99 };
100 #endif
101 
102 #ifndef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
103 class NLIB_CAPABILITY("mutex") TimedCriticalSection {
104  public:
105 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
106  constexpr TimedCriticalSection() NLIB_NOEXCEPT = default;
107 #else
108  TimedCriticalSection() NLIB_NOEXCEPT {
110  NLIB_ASSERT_NOERR(e);
111  NLIB_UNUSED(e);
112  }
113 #endif
114  ~TimedCriticalSection() NLIB_NOEXCEPT { nlib_mutex_destroy(&mutex_); }
115  NLIB_VIS_PUBLIC bool try_lock_for(const TimeSpan& span) NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true);
116  NLIB_VIS_PUBLIC bool try_lock_until(const DateTime& abstime)
117  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true);
118  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
119  errno_t e = nlib_mutex_lock(&mutex_);
120  NLIB_ASSERT_NOERR(e);
121  NLIB_UNUSED(e);
122  }
123  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
124  errno_t e = nlib_mutex_unlock(&mutex_);
125  NLIB_ASSERT_NOERR(e);
126  NLIB_UNUSED(e);
127  }
128  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
129  errno_t e = nlib_mutex_trylock(&mutex_);
130  if (e == 0) return true;
131  NLIB_ASSERT(e == EBUSY);
132  return false;
133  }
135  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
136  return &mutex_;
137  }
138 
139  private:
140 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
142 #else
143  nlib_mutex mutex_;
144 #endif
145 };
146 #endif
147 
148 } // namespace threading
149 NLIB_NAMESPACE_END
150 
151 NLIB_NAMESPACE_BEGIN
152 namespace threading {
153 
154 class DummyCriticalSection {
155  public:
156  NLIB_CEXPR DummyCriticalSection() NLIB_NOEXCEPT {}
157  ~DummyCriticalSection() NLIB_NOEXCEPT {}
158  void lock() NLIB_NOEXCEPT {}
159  void unlock() NLIB_NOEXCEPT {}
160  bool try_lock() NLIB_NOEXCEPT { return true; }
161  bool try_lock_for(const TimeSpan&) NLIB_NOEXCEPT { return true; } // NOLINT
162  bool try_lock_until(const DateTime&) NLIB_NOEXCEPT { return true; } // NOLINT
163  typedef int native_handle_type;
164  native_handle_type native_handle() NLIB_NOEXCEPT { return 0; }
165 
166  private:
167  NLIB_DISALLOW_COPY_AND_ASSIGN(DummyCriticalSection);
168 };
169 
170 class CriticalSectionFallback {
171  public:
172  // NOTE:
173  // -1 must not be a thread-id
174  CriticalSectionFallback() NLIB_NOEXCEPT : counter_(0) {
175  tid_ = -1;
176  }
177  ~CriticalSectionFallback() NLIB_NOEXCEPT {}
178  NLIB_VIS_PUBLIC void lock() NLIB_NOEXCEPT;
179  NLIB_VIS_PUBLIC void unlock() NLIB_NOEXCEPT;
180  NLIB_VIS_PUBLIC bool try_lock() NLIB_NOEXCEPT;
182  native_handle_type native_handle() { return lock_.native_handle(); }
183 
184  private:
185  SimpleCriticalSection lock_;
186  int32_t counter_;
187  nlib_thread_id tid_;
188 };
189 
190 #ifdef NLIB_CRITICALSECTION_USE_FALLBACK
191 typedef CriticalSectionFallback CriticalSection;
192 #endif
193 
194 class TimedCriticalSectionFallback {
195  public:
196  TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
197  ~TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
198  void lock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.lock(); }
199  void unlock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.unlock(); }
200  bool try_lock() NLIB_NOEXCEPT { return lock_.try_lock(); }
201  NLIB_VIS_PUBLIC bool try_lock_for(const TimeSpan& span) NLIB_NOEXCEPT;
202  NLIB_VIS_PUBLIC bool try_lock_until(const DateTime& abstime) NLIB_NOEXCEPT;
204  native_handle_type native_handle() { return lock_.native_handle(); }
205 
206  private:
207  CriticalSection lock_;
208 };
209 
210 #ifdef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
211 typedef TimedCriticalSectionFallback TimedCriticalSection;
212 #endif
213 
214 } // namespace threading
215 NLIB_NAMESPACE_END
216 
217 NLIB_NAMESPACE_BEGIN
218 namespace threading {
219 
220 struct AdoptLockType {};
221 struct TryToLockType {};
222 struct DeferLockType {};
223 
227 
228 template <class T>
229 class NLIB_SCOPED_CAPABILITY ScopedLock {
230  public:
231  typedef T mutex_type;
232  typedef typename mutex_type::native_handle_type native_handle_type;
233  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
234  lock_.lock();
235  }
236  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_ACQUIRE(lock_) // NOLINT
237  : lock_(m) {}
238  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
239  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
240  return lock_.native_handle();
241  }
242 
243  private:
244  mutex_type& lock_;
246 };
247 
248 template <>
249 class NLIB_SCOPED_CAPABILITY ScopedLock<SimpleCriticalSection> {
250  public:
251  typedef SimpleCriticalSection mutex_type;
252  typedef mutex_type::native_handle_type native_handle_type;
253  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
254  lock_.lock();
255  }
256  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(m) // NOLINT
257  NLIB_ACQUIRE(lock_)
258  : lock_(m) {}
259  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
260  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
261  return lock_.native_handle();
262  }
263 
264  private:
265  mutex_type& lock_;
266  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
267 };
268 
269 template<>
270 class NLIB_SCOPED_CAPABILITY ScopedLock<nlib_mutex> {
271  public:
272  typedef nlib_mutex mutex_type;
273  typedef nlib_mutex* native_handle_type;
274  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
275  errno_t e = nlib_mutex_lock(&lock_);
276  NLIB_UNUSED(e);
277  NLIB_ASSERT_NOERR(e);
278  }
279  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(lock_) // NOLINT
280  NLIB_ACQUIRE(lock_)
281  : lock_(m) {}
282  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) {
283  errno_t e = nlib_mutex_unlock(&lock_);
284  NLIB_UNUSED(e);
285  NLIB_ASSERT_NOERR(e);
286  }
287  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) { return &lock_; }
288 
289  private:
290  nlib_mutex& lock_;
291  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
292 };
293 
294 template <class T>
295 class NLIB_SCOPED_CAPABILITY UniqueLock {
296  public:
297  typedef T mutex_type;
298  typedef typename mutex_type::native_handle_type native_handle_type;
299  UniqueLock() NLIB_NOEXCEPT : locker_(NULL), is_locked_(false) {}
300  explicit UniqueLock(mutex_type& rhs) NLIB_ACQUIRE(locker_) :
301  locker_(&rhs), is_locked_(true) { // NOLINT
302  rhs.lock();
303  }
304  UniqueLock(mutex_type& rhs, AdoptLockType) // NOLINT
305  NLIB_REQUIRES(locker_) : locker_(&rhs), is_locked_(true) {}
306  UniqueLock(mutex_type& rhs, DeferLockType) // NOLINT
307  NLIB_NOEXCEPT NLIB_EXCLUDES(locker_)
308  : locker_(&rhs), is_locked_(false) {}
309  UniqueLock(mutex_type& rhs, TryToLockType) // NOLINT
310  : locker_(&rhs),
311  is_locked_(rhs.try_lock()) {}
312  NLIB_MOVE_MEMBER_HELPER_2(UniqueLock, locker_, is_locked_)
313  ~UniqueLock() NLIB_NOEXCEPT NLIB_RELEASE() {
314  if (is_locked_) locker_->unlock();
315  }
316  void lock() NLIB_ACQUIRE() {
317  // no NLIB_NOEXCEPT
318  NLIB_ASSERT(locker_ && !is_locked_);
319  if (!locker_ || is_locked_) {
320  return;
321  }
322  locker_->lock();
323  is_locked_ = true;
324  }
325  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
326  NLIB_ASSERT(locker_ && is_locked_);
327  if (!locker_ || !is_locked_) {
328  return;
329  }
330  locker_->unlock();
331  is_locked_ = false;
332  }
333  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
334  NLIB_ASSERT(locker_ && !is_locked_);
335  if (!locker_ || is_locked_) {
336  return false;
337  }
338  is_locked_ = locker_->try_lock();
339  return is_locked_;
340  }
342  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
343  NLIB_ASSERT(locker_ && !is_locked_);
344  if (!locker_ || is_locked_) {
345  return false;
346  }
347  is_locked_ = locker_->try_lock_for(timeout);
348  return is_locked_;
349  }
351  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
352  NLIB_ASSERT(locker_ && !is_locked_);
353  if (!locker_ || is_locked_) {
354  return false;
355  }
356  is_locked_ = locker_->try_lock_until(abstime);
357  return is_locked_;
358  }
359  void swap(UniqueLock& rhs) NLIB_NOEXCEPT { // NOLINT
360  using std::swap;
361  swap(locker_, rhs.locker_);
362  swap(is_locked_, rhs.is_locked_);
363  }
364  mutex_type* release() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) {
365  mutex_type* p = locker_;
366  locker_ = NULL;
367  is_locked_ = false;
368  return p;
369  }
370  mutex_type* mutex() const NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) {
371  return locker_;
372  }
373  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_) {
374  return locker_->native_handle();
375  }
376  bool owns_lock() const NLIB_NOEXCEPT { return is_locked_; }
377  NLIB_SAFE_BOOL(UniqueLock, owns_lock());
378 
379  private:
380  mutex_type* locker_;
381  bool is_locked_;
383 };
384 
385 namespace detail {
386 
387 template<class T>
388 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(T& obj) NLIB_RETURN_CAPABILITY(obj) { // NOLINT
389  return obj.native_handle();
390 }
391 
392 template<>
393 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(nlib_mutex& obj) NLIB_RETURN_CAPABILITY(obj) { // NOLINT
394  return &obj;
395 }
396 
397 } // namespace detail
398 
399 } // namespace threading
400 NLIB_NAMESPACE_END
401 
402 #ifndef NLIB_STD_SWAP_WORKAROUND
403 NLIB_NAMESPACE_BEGIN
404 #endif
405 
406 NLIB_DEFINE_STD_SWAP_T_BEGIN1(threading) // NOLINT
407 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::UniqueLock) // NOLINT
408 NLIB_DEFINE_STD_SWAP_T_END1(threading) // NOLINT
409 
410 #ifndef NLIB_STD_SWAP_WORKAROUND
411 NLIB_NAMESPACE_END
412 #endif
413 
414 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
415 template<class T>
416 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&) = delete;
417 #else
418 template<class T>
419 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&);
420 #endif
421 
422 #endif // INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
#define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER
A macro for statically initializing nlib_mutex. Makes it a recursive mutex that can time out...
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
Gets a pointer to a native type mutex.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a lock, and attempts to enter the critical section.
UniqueLock() noexcept
Initializes an object without creating an association.
#define NLIB_ALWAYS_INLINE
Indicates that the compiler is forced to perform inline expansion of functions.
Definition: Platform_unix.h:69
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:145
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
Definition: Config.h:160
Simplest critical section. Not reentrant.
mutex_type * mutex() const noexcept NLIB_RETURN_CAPABILITY(*locker_)
Gets the pointer to the associated object like CriticalSection.
mutex_type * release() noexcept NLIB_RETURN_CAPABILITY(*locker_)
Removes the association. Does not unlock.
errno_t nlib_mutex_recursive_timed_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex that is recursive and can time out.
NLIB_CHECK_RESULT bool try_lock_until(const DateTime &abstime) noexcept NLIB_TRY_ACQUIRE(true)
Attempts to lock with timeout the associated CriticalSection or other object.
native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_)
Returns an implementation-specific handle representing a lock.
errno_t nlib_mutex_unlock(nlib_mutex *mutex) NLIB_RELEASE(*mutex)
Unlocks the specified mutex.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a lock, and attempts to enter the critical section.
#define NLIB_MUTEX_INITIALIZER
A macro for statically initializing nlib_mutex.
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
Definition: Platform_unix.h:74
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type.
bool owns_lock() const noexcept
Returns true if the lock associated with UniqueLock is locked.
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type.
UniqueLock(mutex_type &rhs, AdoptLockType) NLIB_REQUIRES(locker_)
Assumes an object like CriticalSection is already locked, and initializes the object without locking ...
errno_t nlib_mutex_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex.
The class for representing the date and time.
Definition: DateTime.h:248
void swap(UniqueLock &rhs) noexcept
Attempts to swap the associated CriticalSection or other object.
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:61
#define NLIB_RECURSIVE_MUTEX_INITIALIZER
A macro for statically initializing nlib_mutex. Makes it a recursive mutex.
native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_)
Returns an implementation-specific handle representing a lock.
errno_t nlib_mutex_lock(nlib_mutex *mutex) NLIB_ACQUIRE(*mutex)
Locks the specified mutex.
Used in ScopedLock and UniqueLock by tag type.
Class to wrap objects like CriticalSection.
nlib_mutex * native_handle_type
typedef to a pointer type to a native mutex.
void lock() noexcept NLIB_ACQUIRE()
Gets a lock, and enters the critical section. Blocks until it can get a lock.
NLIB_CHECK_RESULT bool try_lock_for(const TimeSpan &timeout) noexcept NLIB_TRY_ACQUIRE(true)
Attempts to lock with timeout the associated CriticalSection or other object.
ScopedLock(mutex_type &m) NLIB_ACQUIRE(lock_)
Locks objects like CriticalSection (calls lock).
UniqueLock(mutex_type &rhs, DeferLockType) noexcept NLIB_EXCLUDES(locker_)
Initializes an object without locking.
void unlock() noexcept NLIB_RELEASE()
Releases the lock, and exits the critical section.
Used in ScopedLock and UniqueLock by tag type.
nlib_mutex * native_handle_type
typedef to a pointer type to a native mutex.
nlib_mutex * native_handle_type
typedef to a pointer type to a native mutex.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:86
constexpr const DeferLockType deferLock
A DeferLockType-type value.
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
Definition: Config.h:80
A file that contains the configuration information for each development environment.
constexpr const AdoptLockType adoptLock
An AdoptLockType-type value.
Used in ScopedLock and UniqueLock by tag type.
void unlock() noexcept NLIB_RELEASE()
Unlocks the associated CriticalSection or other object.
NLIB_CHECK_RESULT errno_t nlib_mutex_trylock(nlib_mutex *mutex) NLIB_TRY_ACQUIRE(0
Locks mutex, but only if it is not locked.
UniqueLock(mutex_type &rhs, TryToLockType)
Attempts to lock using try_lock when initializing.
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
Gets a pointer to a native type mutex.
int nlib_thread_id
A unique integer value for each thread.
Definition: Platform.h:1458
Wraps objects like CriticalSection. Locks with a constructor, and unlocks with a destructor.
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
Gets a pointer to a native type mutex.
void lock() NLIB_ACQUIRE()
Locks the associated CriticalSection or other object.
pthread_mutex_t nlib_mutex
The type for mutex variables.
void lock() noexcept NLIB_ACQUIRE()
Gets a lock, and enters the critical section. Blocks until it can get a lock.
void lock() noexcept NLIB_ACQUIRE()
Gets a lock, and enters the critical section. Blocks until it can get a lock.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a lock, and attempts to enter the critical section.
~ScopedLock() noexcept NLIB_RELEASE(lock_)
Unlocks objects like CriticalSection (calls unlock).
The class for representing the time.
Definition: DateTime.h:93
void unlock() noexcept NLIB_RELEASE()
Releases the lock, and exits the critical section.
UniqueLock(mutex_type &rhs) NLIB_ACQUIRE(locker_)
Locks the object like CriticalSection and associates it with this object.
Critical section that can timeout in reentrant.
constexpr const TryToLockType tryToLock
A TryToLockType-type value.
void unlock() noexcept NLIB_RELEASE()
Releases the lock, and exits the critical section.
errno_t nlib_mutex_destroy(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Destroys the specified mutex object and frees any associated resources.
bool nlib_is_error(const T &obj) noexcept
Returns true when the process result or object status is in an erroneous condition.
Definition: Config.h:922
ScopedLock(mutex_type &m, AdoptLockType) noexcept NLIB_ACQUIRE(lock_)
Assumes an object like CriticalSection is already locked, and initializes the object without locking ...
errno_t nlib_mutex_recursive_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a recursive mutex.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Attempts to lock the associated object like CriticalSection.
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24