nlib
CriticalSection.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
17 #define INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
18 
19 #include "nn/nlib/Config.h"
20 #include "nn/nlib/Swap.h"
21 
22 NLIB_NAMESPACE_BEGIN
23 class TimeSpan;
24 class DateTime;
25 namespace threading {
26 
27 class NLIB_CAPABILITY("mutex") SimpleCriticalSection NLIB_FINAL {
28  public:
29 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
30  constexpr SimpleCriticalSection() NLIB_NOEXCEPT = default;
31 #else
33  errno_t e = nlib_mutex_init(&mutex_);
34  NLIB_ASSERT_NOERR(e);
35  NLIB_UNUSED(e);
36  }
37 #endif
39  errno_t e = nlib_mutex_destroy(&mutex_);
40  NLIB_UNUSED(e);
41  NLIB_ASSERT_NOERR(e);
42  }
43  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
44  errno_t e = nlib_mutex_lock(&mutex_);
45  NLIB_UNUSED(e);
46  NLIB_ASSERT_NOERR(e);
47  }
48  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
49  errno_t e = nlib_mutex_unlock(&mutex_);
50  NLIB_UNUSED(e);
51  NLIB_ASSERT_NOERR(e);
52  }
53  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
54  errno_t e = nlib_mutex_trylock(&mutex_);
55  if (e == 0) return true;
56  NLIB_ASSERT(e == EBUSY);
57  return false;
58  }
60  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
61  return &mutex_;
62  }
63 
64  private:
65 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
67 #else
68  nlib_mutex mutex_;
69 #endif
71 };
72 
73 #ifndef NLIB_CRITICALSECTION_USE_FALLBACK
74 class NLIB_CAPABILITY("mutex") CriticalSection NLIB_FINAL {
75  public:
76 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
77  constexpr CriticalSection() NLIB_NOEXCEPT = default;
78 #else
81  NLIB_ASSERT_NOERR(e);
82  NLIB_UNUSED(e);
83  }
84 #endif
86  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
87  errno_t e = nlib_mutex_lock(&mutex_);
88  NLIB_ASSERT_NOERR(e);
89  NLIB_UNUSED(e);
90  }
91  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
92  errno_t e = nlib_mutex_unlock(&mutex_);
93  NLIB_ASSERT_NOERR(e);
94  NLIB_UNUSED(e);
95  }
96  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
97  errno_t e = nlib_mutex_trylock(&mutex_);
98  if (e == 0) return true;
99  NLIB_ASSERT(e == EBUSY);
100  return false;
101  }
103  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
104  return &mutex_;
105  }
106 
107  private:
108 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
110 #else
111  nlib_mutex mutex_;
112 #endif
114 };
115 #endif
116 
117 #ifndef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
118 class NLIB_CAPABILITY("mutex") TimedCriticalSection NLIB_FINAL {
119  public:
120 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
121  constexpr TimedCriticalSection() NLIB_NOEXCEPT = default;
122 #else
125  NLIB_ASSERT_NOERR(e);
126  NLIB_UNUSED(e);
127  }
128 #endif
130  NLIB_VIS_PUBLIC bool try_lock_for(const TimeSpan& span) NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true);
131  NLIB_VIS_PUBLIC bool try_lock_until(const DateTime& abstime) NLIB_NOEXCEPT
132  NLIB_TRY_ACQUIRE(true);
133  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
134  errno_t e = nlib_mutex_lock(&mutex_);
135  NLIB_ASSERT_NOERR(e);
136  NLIB_UNUSED(e);
137  }
138  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
139  errno_t e = nlib_mutex_unlock(&mutex_);
140  NLIB_ASSERT_NOERR(e);
141  NLIB_UNUSED(e);
142  }
143  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
144  errno_t e = nlib_mutex_trylock(&mutex_);
145  if (e == 0) return true;
146  NLIB_ASSERT(e == EBUSY);
147  return false;
148  }
150  native_handle_type native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
151  return &mutex_;
152  }
153 
154  private:
155 #if defined(__cpp_constexpr) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
157 #else
158  nlib_mutex mutex_;
159 #endif
161 };
162 #endif
163 
164 } // namespace threading
165 NLIB_NAMESPACE_END
166 
167 NLIB_NAMESPACE_BEGIN
168 namespace threading {
169 
170 class DummyCriticalSection NLIB_FINAL {
171  public:
172  NLIB_CEXPR DummyCriticalSection() NLIB_NOEXCEPT {}
173  ~DummyCriticalSection() NLIB_NOEXCEPT {}
174  void lock() NLIB_NOEXCEPT {}
175  void unlock() NLIB_NOEXCEPT {}
176  bool try_lock() NLIB_NOEXCEPT { return true; }
177  bool try_lock_for(const TimeSpan&) NLIB_NOEXCEPT { return true; }
178  bool try_lock_until(const DateTime&) NLIB_NOEXCEPT { return true; }
179  typedef int native_handle_type;
180  native_handle_type native_handle() NLIB_NOEXCEPT { return 0; }
181 
182  private:
183  NLIB_DISALLOW_COPY_AND_ASSIGN(DummyCriticalSection);
184 };
185 
186 class CriticalSectionFallback NLIB_FINAL {
187  public:
188  // NOTE:
189  // -1 must not be a thread-id
190  CriticalSectionFallback() NLIB_NOEXCEPT : counter_(0) { tid_ = -1; }
191  ~CriticalSectionFallback() NLIB_NOEXCEPT {}
192  NLIB_VIS_PUBLIC void lock() NLIB_NOEXCEPT;
193  NLIB_VIS_PUBLIC void unlock() NLIB_NOEXCEPT;
194  NLIB_VIS_PUBLIC bool try_lock() NLIB_NOEXCEPT;
195  typedef SimpleCriticalSection::native_handle_type native_handle_type;
196  native_handle_type native_handle() { return lock_.native_handle(); }
197 
198  private:
199  SimpleCriticalSection lock_;
200  int32_t counter_;
201  nlib_thread_id tid_;
202 };
203 
204 #ifdef NLIB_CRITICALSECTION_USE_FALLBACK
205 typedef CriticalSectionFallback CriticalSection;
206 #endif
207 
208 class TimedCriticalSectionFallback NLIB_FINAL {
209  public:
210  TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
211  ~TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
212  void lock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.lock(); }
213  void unlock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.unlock(); }
214  bool try_lock() NLIB_NOEXCEPT { return lock_.try_lock(); }
215  NLIB_VIS_PUBLIC bool try_lock_for(const TimeSpan& span) NLIB_NOEXCEPT;
216  NLIB_VIS_PUBLIC bool try_lock_until(const DateTime& abstime) NLIB_NOEXCEPT;
217  typedef CriticalSection::native_handle_type native_handle_type;
218  native_handle_type native_handle() { return lock_.native_handle(); }
219 
220  private:
221  CriticalSection lock_;
222 };
223 
224 #ifdef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
225 typedef TimedCriticalSectionFallback TimedCriticalSection;
226 #endif
227 
228 } // namespace threading
229 NLIB_NAMESPACE_END
230 
231 NLIB_NAMESPACE_BEGIN
232 namespace threading {
233 
234 struct AdoptLockType {};
235 struct TryToLockType {};
236 struct DeferLockType {};
237 
241 
242 template<class T>
243 class NLIB_SCOPED_CAPABILITY ScopedLock NLIB_FINAL {
244  public:
245  typedef T mutex_type;
246  typedef typename mutex_type::native_handle_type native_handle_type;
247  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { lock_.lock(); }
248  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_ACQUIRE(lock_) : lock_(m) {}
249  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
250  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
251  return lock_.native_handle();
252  }
253 
254  private:
255  mutex_type& lock_;
257 };
258 
259 template<>
260 class NLIB_SCOPED_CAPABILITY ScopedLock<SimpleCriticalSection> NLIB_FINAL {
261  public:
262  typedef SimpleCriticalSection mutex_type;
263  typedef mutex_type::native_handle_type native_handle_type;
264  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { lock_.lock(); }
265  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(m) NLIB_ACQUIRE(lock_) :
266  lock_(m) {}
267  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
268  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
269  return lock_.native_handle();
270  }
271 
272  private:
273  mutex_type& lock_;
274  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
275 };
276 
277 template<>
278 class NLIB_SCOPED_CAPABILITY ScopedLock<nlib_mutex> NLIB_FINAL {
279  public:
280  typedef nlib_mutex mutex_type;
281  typedef nlib_mutex* native_handle_type;
282  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) {
283  errno_t e = nlib_mutex_lock(&lock_);
284  NLIB_UNUSED(e);
285  NLIB_ASSERT_NOERR(e);
286  }
287  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(lock_)
288  NLIB_ACQUIRE(lock_) :
289  lock_(m) {}
290  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) {
291  errno_t e = nlib_mutex_unlock(&lock_);
292  NLIB_UNUSED(e);
293  NLIB_ASSERT_NOERR(e);
294  }
295  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) { return &lock_; }
296 
297  private:
298  nlib_mutex& lock_;
299  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
300 };
301 
302 template<class T>
303 class NLIB_SCOPED_CAPABILITY UniqueLock NLIB_FINAL {
304  public:
305  typedef T mutex_type;
306  typedef typename mutex_type::native_handle_type native_handle_type;
307  UniqueLock() NLIB_NOEXCEPT : locker_(nullptr), is_locked_(false) {}
308  explicit UniqueLock(mutex_type& rhs) NLIB_ACQUIRE(locker_) : locker_(&rhs), is_locked_(true) {
309  rhs.lock();
310  }
311  UniqueLock(mutex_type& rhs, AdoptLockType) NLIB_REQUIRES(locker_) :
312  locker_(&rhs),
313  is_locked_(true) {}
314  UniqueLock(mutex_type& rhs, DeferLockType) NLIB_NOEXCEPT NLIB_EXCLUDES(locker_) :
315  locker_(&rhs),
316  is_locked_(false) {}
317  UniqueLock(mutex_type& rhs, TryToLockType) : locker_(&rhs), is_locked_(rhs.try_lock()) {}
318  ~UniqueLock() NLIB_NOEXCEPT NLIB_RELEASE() {
319  if (is_locked_) locker_->unlock();
320  }
321 #ifdef __cpp_rvalue_references
322  UniqueLock(UniqueLock&& rhs) NLIB_NOEXCEPT : locker_(rhs.locker_), is_locked_(rhs.is_locked_) {
323  rhs.locker_ = nullptr;
324  rhs.is_locked_ = false;
325  }
327  locker_ = rhs.locker_;
328  is_locked_ = rhs.is_locked_;
329  rhs.locker_ = nullptr;
330  rhs.is_locked_ = false;
331  return *this;
332  }
333 #endif
334  UniqueLock(UniqueLock& rhs, move_tag) NLIB_NOEXCEPT : locker_(rhs.locker_),
335  is_locked_(rhs.is_locked_) {
336  rhs.locker_ = nullptr;
337  rhs.is_locked_ = false;
338  }
340  locker_ = rhs.locker_;
341  is_locked_ = rhs.is_locked_;
342  rhs.locker_ = nullptr;
343  rhs.is_locked_ = false;
344  return *this;
345  }
346  void lock() NLIB_ACQUIRE() {
347  // no NLIB_NOEXCEPT
348  NLIB_ASSERT(locker_ && !is_locked_);
349  if (!locker_ || is_locked_) {
350  return;
351  }
352  locker_->lock();
353  is_locked_ = true;
354  }
355  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
356  NLIB_ASSERT(locker_ && is_locked_);
357  if (!locker_ || !is_locked_) {
358  return;
359  }
360  locker_->unlock();
361  is_locked_ = false;
362  }
363  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
364  NLIB_ASSERT(locker_ && !is_locked_);
365  if (!locker_ || is_locked_) {
366  return false;
367  }
368  is_locked_ = locker_->try_lock();
369  return is_locked_;
370  }
372  NLIB_TRY_ACQUIRE(true) {
373  NLIB_ASSERT(locker_ && !is_locked_);
374  if (!locker_ || is_locked_) {
375  return false;
376  }
377  is_locked_ = locker_->try_lock_for(timeout);
378  return is_locked_;
379  }
381  NLIB_TRY_ACQUIRE(true) {
382  NLIB_ASSERT(locker_ && !is_locked_);
383  if (!locker_ || is_locked_) {
384  return false;
385  }
386  is_locked_ = locker_->try_lock_until(abstime);
387  return is_locked_;
388  }
389  mutex_type* release() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) {
390  mutex_type* p = locker_;
391  locker_ = nullptr;
392  is_locked_ = false;
393  return p;
394  }
395  mutex_type* mutex() const NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) { return locker_; }
396  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_) {
397  return locker_->native_handle();
398  }
399  bool owns_lock() const NLIB_NOEXCEPT { return is_locked_; }
400  NLIB_SAFE_BOOL(UniqueLock, owns_lock());
401 
402  private:
403  mutex_type* locker_;
404  bool is_locked_;
406 };
407 
408 namespace detail {
409 
410 template<class T>
411 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(T& obj) NLIB_RETURN_CAPABILITY(obj) {
412  return obj.native_handle();
413 }
414 
415 template<>
416 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(nlib_mutex& obj) NLIB_RETURN_CAPABILITY(obj) {
417  return &obj;
418 }
419 
420 } // namespace detail
421 
422 } // namespace threading
423 NLIB_NAMESPACE_END
424 
425 NLIB_DEFINE_STD_SWAP_T_BEGIN3(nn, nlib, threading)
426 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::UniqueLock)
427 NLIB_DEFINE_STD_SWAP_T_END3(nn, nlib, threading)
428 
429 #if defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) && !defined(NLIB_DOXYGEN)
430 template<class T>
431 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&) = delete;
432 #else
433 template<class T>
434 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&);
435 #endif
436 
437 #endif // INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
UniqueLock & assign(UniqueLock &rhs, move_tag) noexcept
Corresponds to a move assignment operator.
#define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER
A macro for statically initializing nlib_mutex. Makes it a recursive mutex that can time out...
UniqueLock(UniqueLock &rhs, move_tag) noexcept
Corresponds to a move constructor.
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
Gets a pointer to a native type mutex.
bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a lock, and attempts to enter the critical section.
UniqueLock() noexcept
Instantiates the object with default parameters (default constructor). Initializes an object without ...
#define NLIB_ALWAYS_INLINE
Indicates that the compiler is forced to perform inline expansion of functions.
Definition: Platform_unix.h:95
#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:183
#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:199
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.
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.
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: Base64.h:25
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:231
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:87
#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.
An empty structure indicating that an argument to a function needs to be moved.
Definition: Config.h:270
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.
UniqueLock & operator=(UniqueLock &&rhs) noexcept
Move assignment operator.
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:109
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:111
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.
UniqueLock(UniqueLock &&rhs) noexcept
Instantiates the object (move constructor).
void unlock() noexcept NLIB_RELEASE()
Unlocks the associated CriticalSection or other object.
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:1243
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.
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).
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:250
The class for representing the time.
Definition: DateTime.h:97
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:658
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.
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:37