3 #ifndef INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
4 #define INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
7 #include "nn/nlib/Swap.h"
16 #ifdef NLIB_CXX11_CONSTEXPR
43 if (e == 0)
return true;
44 NLIB_ASSERT(e == EBUSY);
54 #ifndef NLIB_CRITICALSECTION_USE_FALLBACK
57 #if defined(NLIB_CXX11_CONSTEXPR)
80 if (e == 0)
return true;
81 NLIB_ASSERT(e == EBUSY);
92 #ifndef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
95 #if defined(NLIB_CXX11_CONSTEXPR)
101 NLIB_ASSERT_NOERR(e);
110 NLIB_ASSERT_NOERR(e);
115 NLIB_ASSERT_NOERR(e);
120 if (e == 0)
return true;
121 NLIB_ASSERT(e == EBUSY);
136 namespace threading {
138 class DummyCriticalSection {
145 bool try_lock_for(
const TimeSpan&)
NLIB_NOEXCEPT {
return true; }
146 bool try_lock_until(
const DateTime&)
NLIB_NOEXCEPT {
return true; }
147 typedef int native_handle_type;
148 native_handle_type native_handle()
NLIB_NOEXCEPT {
return 0; }
154 class CriticalSectionFallback {
165 typedef SimpleCriticalSection::native_handle_type native_handle_type;
166 native_handle_type native_handle() {
return m_Lock.native_handle(); }
169 SimpleCriticalSection m_Lock;
174 #ifdef NLIB_CRITICALSECTION_USE_FALLBACK
175 typedef CriticalSectionFallback CriticalSection;
178 class TimedCriticalSectionFallback {
187 typedef CriticalSection::native_handle_type native_handle_type;
188 native_handle_type native_handle() {
return m_Lock.native_handle(); }
191 CriticalSection m_Lock;
194 #ifdef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK
195 typedef TimedCriticalSectionFallback TimedCriticalSection;
202 namespace threading {
217 explicit ScopedLock(mutex_type& m) NLIB_LOCK_FUNC(m_Lock) : m_Lock(m) {
231 class NLIB_SCOPED_LOCKABLE ScopedLock<SimpleCriticalSection> {
233 typedef SimpleCriticalSection mutex_type;
234 typedef mutex_type::native_handle_type native_handle_type;
235 explicit ScopedLock(mutex_type& m) NLIB_LOCK_FUNC(m_Lock) : m_Lock(m) {
238 ScopedLock(mutex_type& m, AdoptLockType)
NLIB_NOEXCEPT NLIB_LOCK_REQUIRED(m)
239 NLIB_LOCK_FUNC(m_Lock)
241 ~ScopedLock()
NLIB_NOEXCEPT NLIB_UNLOCK_FUNC(m_Lock) { m_Lock.unlock(); }
242 native_handle_type native_handle() {
return m_Lock.native_handle(); }
250 class NLIB_SCOPED_LOCKABLE ScopedLock<
nlib_mutex> {
254 explicit ScopedLock(mutex_type& m) NLIB_LOCK_FUNC(m_Lock) : m_Lock(m) {
257 NLIB_ASSERT_NOERR(e);
259 ScopedLock(mutex_type& m, AdoptLockType)
NLIB_NOEXCEPT NLIB_LOCK_REQUIRED(m)
260 NLIB_LOCK_FUNC(m_Lock)
265 NLIB_ASSERT_NOERR(e);
267 native_handle_type native_handle() {
return &m_Lock; }
280 explicit UniqueLock(mutex_type& rhs) : m_Locker(&rhs), m_Locked(true) {
291 m_Locked(rhs.try_lock()) {}
292 NLIB_MOVE_MEMBER_HELPER_2(
UniqueLock, m_Locker, m_Locked)
294 if (m_Locked) m_Locker->unlock();
297 NLIB_ASSERT(m_Locker && !m_Locked);
298 if (!m_Locker || m_Locked) {
305 NLIB_ASSERT(m_Locker && m_Locked);
306 if (!m_Locker || !m_Locked) {
313 NLIB_ASSERT(m_Locker && !m_Locked);
314 if (!m_Locker || m_Locked) {
317 m_Locked = m_Locker->try_lock();
321 NLIB_ASSERT(m_Locker && !m_Locked);
322 if (!m_Locker || m_Locked) {
325 m_Locked = m_Locker->try_lock_for(timeout);
329 NLIB_ASSERT(m_Locker && !m_Locked);
330 if (!m_Locker || m_Locked) {
333 m_Locked = m_Locker->try_lock_until(abstime);
338 swap(m_Locker, rhs.m_Locker);
339 swap(m_Locked, rhs.m_Locked);
342 mutex_type* p = m_Locker;
353 mutex_type* m_Locker;
362 return obj.native_handle();
375 #ifndef NLIB_STD_SWAP_WORKAROUND
379 NLIB_DEFINE_STD_SWAP_T_BEGIN1(threading)
380 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::UniqueLock)
381 NLIB_DEFINE_STD_SWAP_T_END1(threading)
383 #ifndef NLIB_STD_SWAP_WORKAROUND
388 #endif // INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
UniqueLock() noexcept
関連付けなしにオブジェクトを初期化します。
native_handle_type native_handle() noexcept
ネイティブ型のミューテックスのポインタを取得します。
bool owns_lock() const noexcept
UniqueLockに関連付けられたロックがロックされていればtrueを返します。
void lock() noexcept
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
~ScopedLock() noexcept NLIB_UNLOCK_FUNC(m_Lock)
CriticalSection等をアンロックします(unlock()を呼び出します)。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
bool try_lock() noexcept NLIB_TRYLOCK_FUNC(true)
ロックを取得し、クリティカルセクションに入ることを試みます。
最も単純なクリティカルセクションです。リエントラントではありません。
mutex_type * release() noexcept
関連付けを解除します。アンロックはされません。
ScopedLock(mutex_type &m, AdoptLockType) noexcept NLIB_LOCK_FUNC(m_Lock)
CriticalSection等が既にロックされていると仮定して、ロックせずにオブジェクトを初期化します。 デストラ...
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type
UniqueLock(mutex_type &rhs, AdoptLockType)
CriticalSection等が既にロックされていると仮定して、ロックせずにオブジェクトを初期化します。 デストラ...
bool try_lock() noexcept
関連付けられたCriticalSection等のロックを試みます。
void unlock() noexcept
ロックを開放し、クリティカルセクションから出ます。
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type
void swap(UniqueLock &rhs) noexcept
関連付けられているCriticalSection等のオブジェクトをスワップします。
native_handle_type native_handle()
ロックを表す実装固有のハンドルを返します。
constexpr SimpleCriticalSection() noexcept
デフォルトコンストラクタです。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
void unlock() noexcept
ロックを開放し、クリティカルセクションから出ます。
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
constexpr CriticalSection() noexcept
デフォルトコンストラクタです。
void lock() noexcept NLIB_LOCK_FUNC()
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
CriticalSection等をラップするためのクラスです。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
bool try_lock() noexcept
ロックを取得し、クリティカルセクションに入ることを試みます。
native_handle_type native_handle()
ロックを表す実装固有のハンドルを返します。
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
nlib_mutex * native_handle_type
ネイティブのミューテックスへのポインタ型のtypedefです。
ScopedLock(mutex_type &m) NLIB_LOCK_FUNC(m_Lock)
CriticalSection等をロックします(lock()を呼び出します)。
bool try_lock_for(const TimeSpan &timeout) noexcept
関連付けられたCriticalSection等のタイムアウト付きロックを試みます。
constexpr const DeferLockType deferLock
DeferLockType 型の値です。
constexpr const AdoptLockType adoptLock
AdoptLockType 型の値です。
タグ用の型でScopedLockとUniqueLockにおいて利用されます。
void lock() noexcept
ロックを取得し、クリティカルセクションに入ります。取得できるまでブロックします。
UniqueLock(mutex_type &rhs, TryToLockType)
初期化の際にtry_lock()でロックを試みます。
CriticalSection等をラップしてコンストラクタでロック、デストラクタでアンロックします。 ...
void unlock() noexcept NLIB_UNLOCK_FUNC()
ロックを開放し、クリティカルセクションから出ます。
UniqueLock(mutex_type &rhs)
CriticalSection等をロックして、このオブジェクトに関連付けます。
リエントラントでタイムアウトが可能なクリティカルセクションです。
native_handle_type native_handle() noexcept
ネイティブ型のミューテックスのポインタを取得します。
constexpr const TryToLockType tryToLock
TryToLockType 型の値です。
void unlock() noexcept
関連付けられたCriticalSection等をアンロックします。
bool try_lock() noexcept
ロックを取得し、クリティカルセクションに入ることを試みます。
UniqueLock(mutex_type &rhs, DeferLockType) noexcept
ロックせずにオブジェクトを初期化します。
constexpr TimedCriticalSection() noexcept
デフォルトコンストラクタです。
void lock()
関連付けられたCriticalSection等をロックします。
mutex_type * mutex() const noexcept
関連付けられているCriticalSection等のオブジェクトへのポインタを取得します。
bool try_lock_until(const DateTime &abstime) noexcept
関連付けられたCriticalSection等のタイムアウト付きロックを試みます。
native_handle_type native_handle() noexcept
ネイティブ型のミューテックスのポインタを取得します。