nlib
CriticalSection.h
[詳解]
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
32  SimpleCriticalSection() NLIB_NOEXCEPT {
33  errno_t e = nlib_mutex_init(&mutex_);
34  NLIB_ASSERT_NOERR(e);
35  NLIB_UNUSED(e);
36  }
37 #endif
38  ~SimpleCriticalSection() NLIB_NOEXCEPT {
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
79  CriticalSection() NLIB_NOEXCEPT {
81  NLIB_ASSERT_NOERR(e);
82  NLIB_UNUSED(e);
83  }
84 #endif
85  ~CriticalSection() NLIB_NOEXCEPT { nlib_mutex_destroy(&mutex_); }
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
123  TimedCriticalSection() NLIB_NOEXCEPT {
125  NLIB_ASSERT_NOERR(e);
126  NLIB_UNUSED(e);
127  }
128 #endif
129  ~TimedCriticalSection() NLIB_NOEXCEPT { nlib_mutex_destroy(&mutex_); }
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)
132  NLIB_NOEXCEPT 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; } // NOLINT
178  bool try_lock_until(const DateTime&) NLIB_NOEXCEPT { return true; } // NOLINT
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) {
191  tid_ = -1;
192  }
193  ~CriticalSectionFallback() NLIB_NOEXCEPT {}
194  NLIB_VIS_PUBLIC void lock() NLIB_NOEXCEPT;
195  NLIB_VIS_PUBLIC void unlock() NLIB_NOEXCEPT;
196  NLIB_VIS_PUBLIC bool try_lock() NLIB_NOEXCEPT;
198  native_handle_type native_handle() { return lock_.native_handle(); }
199 
200  private:
201  SimpleCriticalSection lock_;
202  int32_t counter_;
203  nlib_thread_id tid_;
204 };
205 
206 #ifdef NLIB_CRITICALSECTION_USE_FALLBACK
207 typedef CriticalSectionFallback CriticalSection;
208 #endif
209 
210 class TimedCriticalSectionFallback NLIB_FINAL {
211  public:
212  TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
213  ~TimedCriticalSectionFallback() NLIB_NOEXCEPT {}
214  void lock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.lock(); }
215  void unlock() NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.unlock(); }
216  bool try_lock() NLIB_NOEXCEPT { return lock_.try_lock(); }
217  NLIB_VIS_PUBLIC bool try_lock_for(const TimeSpan& span) NLIB_NOEXCEPT;
218  NLIB_VIS_PUBLIC bool try_lock_until(const DateTime& abstime) NLIB_NOEXCEPT;
220  native_handle_type native_handle() { return lock_.native_handle(); }
221 
222  private:
223  CriticalSection lock_;
224 };
225 
226 #ifdef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
227 typedef TimedCriticalSectionFallback TimedCriticalSection;
228 #endif
229 
230 } // namespace threading
231 NLIB_NAMESPACE_END
232 
233 NLIB_NAMESPACE_BEGIN
234 namespace threading {
235 
236 struct AdoptLockType {};
237 struct TryToLockType {};
238 struct DeferLockType {};
239 
243 
244 template <class T>
245 class NLIB_SCOPED_CAPABILITY ScopedLock NLIB_FINAL {
246  public:
247  typedef T mutex_type;
248  typedef typename mutex_type::native_handle_type native_handle_type;
249  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
250  lock_.lock();
251  }
252  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_ACQUIRE(lock_) // NOLINT
253  : lock_(m) {}
254  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
255  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
256  return lock_.native_handle();
257  }
258 
259  private:
260  mutex_type& lock_;
262 };
263 
264 template <>
265 class NLIB_SCOPED_CAPABILITY ScopedLock<SimpleCriticalSection> NLIB_FINAL {
266  public:
267  typedef SimpleCriticalSection mutex_type;
268  typedef mutex_type::native_handle_type native_handle_type;
269  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
270  lock_.lock();
271  }
272  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(m) // NOLINT
273  NLIB_ACQUIRE(lock_)
274  : lock_(m) {}
275  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
276  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
277  return lock_.native_handle();
278  }
279 
280  private:
281  mutex_type& lock_;
282  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
283 };
284 
285 template<>
286 class NLIB_SCOPED_CAPABILITY ScopedLock<nlib_mutex> NLIB_FINAL {
287  public:
288  typedef nlib_mutex mutex_type;
289  typedef nlib_mutex* native_handle_type;
290  explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) { // NOLINT
291  errno_t e = nlib_mutex_lock(&lock_);
292  NLIB_UNUSED(e);
293  NLIB_ASSERT_NOERR(e);
294  }
295  ScopedLock(mutex_type& m, AdoptLockType) NLIB_NOEXCEPT NLIB_REQUIRES(lock_) // NOLINT
296  NLIB_ACQUIRE(lock_)
297  : lock_(m) {}
298  ~ScopedLock() NLIB_NOEXCEPT NLIB_RELEASE(lock_) {
299  errno_t e = nlib_mutex_unlock(&lock_);
300  NLIB_UNUSED(e);
301  NLIB_ASSERT_NOERR(e);
302  }
303  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) { return &lock_; }
304 
305  private:
306  nlib_mutex& lock_;
307  NLIB_DISALLOW_COPY_AND_ASSIGN(ScopedLock);
308 };
309 
310 template <class T>
311 class NLIB_SCOPED_CAPABILITY UniqueLock NLIB_FINAL {
312  public:
313  typedef T mutex_type;
314  typedef typename mutex_type::native_handle_type native_handle_type;
315  UniqueLock() NLIB_NOEXCEPT : locker_(nullptr), is_locked_(false) {}
316  explicit UniqueLock(mutex_type& rhs) NLIB_ACQUIRE(locker_) :
317  locker_(&rhs), is_locked_(true) { // NOLINT
318  rhs.lock();
319  }
320  UniqueLock(mutex_type& rhs, AdoptLockType) // NOLINT
321  NLIB_REQUIRES(locker_) : locker_(&rhs), is_locked_(true) {}
322  UniqueLock(mutex_type& rhs, DeferLockType) // NOLINT
323  NLIB_NOEXCEPT NLIB_EXCLUDES(locker_)
324  : locker_(&rhs), is_locked_(false) {}
325  UniqueLock(mutex_type& rhs, TryToLockType) // NOLINT
326  : locker_(&rhs),
327  is_locked_(rhs.try_lock()) {}
328  ~UniqueLock() NLIB_NOEXCEPT NLIB_RELEASE() {
329  if (is_locked_) locker_->unlock();
330  }
331 #ifdef __cpp_rvalue_references
333  : locker_(rhs.locker_), is_locked_(rhs.is_locked_) {
334  rhs.locker_ = nullptr;
335  rhs.is_locked_ = false;
336  }
338  locker_ = rhs.locker_;
339  is_locked_ = rhs.is_locked_;
340  rhs.locker_ = nullptr;
341  rhs.is_locked_ = false;
342  return *this;
343  }
344 #endif
346  : locker_(rhs.locker_), is_locked_(rhs.is_locked_) {
347  rhs.locker_ = nullptr;
348  rhs.is_locked_ = false;
349  }
351  locker_ = rhs.locker_;
352  is_locked_ = rhs.is_locked_;
353  rhs.locker_ = nullptr;
354  rhs.is_locked_ = false;
355  return *this;
356  }
358  using std::swap;
359  swap(locker_, rhs.locker_);
360  swap(is_locked_, rhs.is_locked_);
361  }
362  void lock() NLIB_ACQUIRE() {
363  // no NLIB_NOEXCEPT
364  NLIB_ASSERT(locker_ && !is_locked_);
365  if (!locker_ || is_locked_) {
366  return;
367  }
368  locker_->lock();
369  is_locked_ = true;
370  }
371  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
372  NLIB_ASSERT(locker_ && is_locked_);
373  if (!locker_ || !is_locked_) {
374  return;
375  }
376  locker_->unlock();
377  is_locked_ = false;
378  }
379  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
380  NLIB_ASSERT(locker_ && !is_locked_);
381  if (!locker_ || is_locked_) {
382  return false;
383  }
384  is_locked_ = locker_->try_lock();
385  return is_locked_;
386  }
388  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
389  NLIB_ASSERT(locker_ && !is_locked_);
390  if (!locker_ || is_locked_) {
391  return false;
392  }
393  is_locked_ = locker_->try_lock_for(timeout);
394  return is_locked_;
395  }
397  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
398  NLIB_ASSERT(locker_ && !is_locked_);
399  if (!locker_ || is_locked_) {
400  return false;
401  }
402  is_locked_ = locker_->try_lock_until(abstime);
403  return is_locked_;
404  }
405  mutex_type* release() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) {
406  mutex_type* p = locker_;
407  locker_ = nullptr;
408  is_locked_ = false;
409  return p;
410  }
411  mutex_type* mutex() const NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(*locker_) {
412  return locker_;
413  }
414  native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_) {
415  return locker_->native_handle();
416  }
417  bool owns_lock() const NLIB_NOEXCEPT { return is_locked_; }
418  NLIB_SAFE_BOOL(UniqueLock, owns_lock());
419 
420  private:
421  mutex_type* locker_;
422  bool is_locked_;
424 };
425 
426 namespace detail {
427 
428 template<class T>
429 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(T& obj) NLIB_RETURN_CAPABILITY(obj) { // NOLINT
430  return obj.native_handle();
431 }
432 
433 template<>
434 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(nlib_mutex& obj) NLIB_RETURN_CAPABILITY(obj) { // NOLINT
435  return &obj;
436 }
437 
438 } // namespace detail
439 
440 } // namespace threading
441 NLIB_NAMESPACE_END
442 
443 NLIB_DEFINE_STD_SWAP_T_BEGIN3(nn, nlib, threading) // NOLINT
444 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::UniqueLock) // NOLINT
445 NLIB_DEFINE_STD_SWAP_T_END3(nn, nlib, threading) // NOLINT
446 
447 #if defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) && !defined(NLIB_DOXYGEN)
448 template<class T>
449 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&) = delete;
450 #else
451 template<class T>
452 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&);
453 #endif
454 
455 #endif // INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
UniqueLock & assign(UniqueLock &rhs, move_tag) noexcept
ムーブ代入演算子に相当します。
#define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER
nlib_mutexを静的に初期化するためのマクロ。再帰でタイムアウト可能なmutexになる。
UniqueLock(UniqueLock &rhs, move_tag) noexcept
ムーブコンストラクタに相当します。
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
ネイティブ型のミューテックスのポインタを取得します。
bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
ロックを取得し、クリティカルセクションに入ることを試みます。
UniqueLock() noexcept
関連付けなしにオブジェクトを初期化します。
#define NLIB_ALWAYS_INLINE
コンパイラに関数をインライン展開するように強く示します。
Definition: Platform_unix.h:97
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:179
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
Definition: Config.h:194
最も単純なクリティカルセクションです。リエントラントではありません。
mutex_type * mutex() const noexcept NLIB_RETURN_CAPABILITY(*locker_)
関連付けられているCriticalSection等のオブジェクトへのポインタを取得します。
mutex_type * release() noexcept NLIB_RETURN_CAPABILITY(*locker_)
関連付けを解除します。アンロックはされません。
errno_t nlib_mutex_recursive_timed_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
再帰かつタイムアウト可能なミューテックスを初期化します。
bool try_lock_until(const DateTime &abstime) noexcept NLIB_TRY_ACQUIRE(true)
関連付けられたCriticalSection等のタイムアウト付きロックを試みます。
native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_)
ロックを表す実装固有のハンドルを返します。
errno_t nlib_mutex_unlock(nlib_mutex *mutex) NLIB_RELEASE(*mutex)
与えられたmutex をアンロックします。
bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
ロックを取得し、クリティカルセクションに入ることを試みます。
#define NLIB_MUTEX_INITIALIZER
nlib_mutexを静的に初期化するためのマクロ。
#define NLIB_CHECK_RESULT
関数の呼び出し元が戻り値をチェックする必要があることを示します。
Definition: Base64.h:25
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type
bool owns_lock() const noexcept
UniqueLockに関連付けられたロックがロックされていればtrueを返します。
#define NLIB_DEPRECATED
関数等がdeprecatedになったことを示します。
Definition: Config.h:109
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type
UniqueLock(mutex_type &rhs, AdoptLockType) NLIB_REQUIRES(locker_)
CriticalSection等が既にロックされていると仮定して、ロックせずにオブジェクトを初期化します。 デストラ...
errno_t nlib_mutex_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
ミューテックスを初期化します。
日時を表すクラスです。
Definition: DateTime.h:246
void swap(UniqueLock &rhs) noexcept
関連付けられているCriticalSection等のオブジェクトをスワップします。
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:89
#define NLIB_RECURSIVE_MUTEX_INITIALIZER
nlib_mutexを静的に初期化するためのマクロ。再帰mutexになる。
native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_)
ロックを表す実装固有のハンドルを返します。
errno_t nlib_mutex_lock(nlib_mutex *mutex) NLIB_ACQUIRE(*mutex)
与えられたmutexをロックします。
空の構造体で、関数の引数をムーブすべきことを示すために利用されます。
Definition: Config.h:265
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
CriticalSection等をラップするためのクラスです。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
void lock() noexcept NLIB_ACQUIRE()
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
UniqueLock & operator=(UniqueLock &&rhs) noexcept
ムーブ代入演算子です。C++11の利用時に有効です。
bool try_lock_for(const TimeSpan &timeout) noexcept NLIB_TRY_ACQUIRE(true)
関連付けられたCriticalSection等のタイムアウト付きロックを試みます。
ScopedLock(mutex_type &m) NLIB_ACQUIRE(lock_)
CriticalSection等をロックします(lock()を呼び出します)。
UniqueLock(mutex_type &rhs, DeferLockType) noexcept NLIB_EXCLUDES(locker_)
ロックせずにオブジェクトを初期化します。
void unlock() noexcept NLIB_RELEASE()
ロックを開放し、クリティカルセクションから出ます。
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Config.h:105
constexpr const DeferLockType deferLock
DeferLockType 型の値です。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
Definition: Config.h:107
開発環境別の設定が書かれるファイルです。
constexpr const AdoptLockType adoptLock
AdoptLockType 型の値です。
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
UniqueLock(UniqueLock &&rhs) noexcept
ムーブコンストラクタです。C++11の利用時に有効です。
void unlock() noexcept NLIB_RELEASE()
関連付けられたCriticalSection等をアンロックします。
errno_t nlib_mutex_trylock(nlib_mutex *mutex) NLIB_TRY_ACQUIRE(0
mutexがロックされていない場合のみロックします。
UniqueLock(mutex_type &rhs, TryToLockType)
初期化の際にtry_lock()でロックを試みます。
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
ネイティブ型のミューテックスのポインタを取得します。
int nlib_thread_id
スレッド毎にユニークな整数値
Definition: Platform.h:1247
CriticalSection等をラップしてコンストラクタでロック、デストラクタでアンロックします。 ...
native_handle_type native_handle() noexcept NLIB_RETURN_CAPABILITY(mutex_)
ネイティブ型のミューテックスのポインタを取得します。
void lock() NLIB_ACQUIRE()
関連付けられたCriticalSection等をロックします。
pthread_mutex_t nlib_mutex
ミューテックス変数の型です。
void lock() noexcept NLIB_ACQUIRE()
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
void lock() noexcept NLIB_ACQUIRE()
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
ロックを取得し、クリティカルセクションに入ることを試みます。
~ScopedLock() noexcept NLIB_RELEASE(lock_)
CriticalSection等をアンロックします(unlock()を呼び出します)。
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
Definition: Config.h:245
時間を表すクラスです。
Definition: DateTime.h:97
void unlock() noexcept NLIB_RELEASE()
ロックを開放し、クリティカルセクションから出ます。
UniqueLock(mutex_type &rhs) NLIB_ACQUIRE(locker_)
CriticalSection等をロックして、このオブジェクトに関連付けます。
リエントラントでタイムアウトが可能なクリティカルセクションです。
constexpr const TryToLockType tryToLock
TryToLockType 型の値です。
リエントラントなミューテックスです。
void unlock() noexcept NLIB_RELEASE()
ロックを開放し、クリティカルセクションから出ます。
errno_t nlib_mutex_destroy(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
mutexオブジェクトを破壊し、関連付けられているリソース(あれば)を解放します。
bool nlib_is_error(const T &obj) noexcept
処理の結果やオブジェクトの状態がエラーである場合にtrueを返します。
Definition: Config.h:682
ScopedLock(mutex_type &m, AdoptLockType) noexcept NLIB_ACQUIRE(lock_)
CriticalSection等が既にロックされていると仮定して、ロックせずにオブジェクトを初期化します。 デストラ...
errno_t nlib_mutex_recursive_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
再帰ミューテックスを初期化します。
bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
関連付けられたCriticalSection等のロックを試みます。
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37