16 #ifndef INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_ 17 #define INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_ 20 #include "nn/nlib/Swap.h" 29 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 43 void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
48 void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
55 if (e == 0)
return true;
56 NLIB_ASSERT(e == EBUSY);
60 native_handle_type
native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
65 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 72 #ifndef NLIB_CRITICALSECTION_USE_FALLBACK 75 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 85 void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
90 void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
97 if (e == 0)
return true;
98 NLIB_ASSERT(e == EBUSY);
102 native_handle_type
native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
107 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 115 #ifndef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK 118 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 123 NLIB_ASSERT_NOERR(e);
130 NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(
true);
131 void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
133 NLIB_ASSERT_NOERR(e);
136 void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
138 NLIB_ASSERT_NOERR(e);
143 if (e == 0)
return true;
144 NLIB_ASSERT(e == EBUSY);
148 native_handle_type
native_handle() NLIB_NOEXCEPT NLIB_RETURN_CAPABILITY(mutex_) {
153 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS) 165 namespace threading {
167 class DummyCriticalSection {
177 native_handle_type native_handle()
NLIB_NOEXCEPT {
return 0; }
183 class CriticalSectionFallback {
195 native_handle_type native_handle() {
return lock_.native_handle(); }
203 #ifdef NLIB_CRITICALSECTION_USE_FALLBACK 207 class TimedCriticalSectionFallback {
211 void lock()
NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.lock(); }
212 void unlock()
NLIB_NOEXCEPT NLIB_NO_THREAD_SAFETY_ANALYSIS { lock_.unlock(); }
217 native_handle_type native_handle() {
return lock_.native_handle(); }
220 CriticalSection lock_;
223 #ifdef NLIB_TIMEDCRITICALSECTION_USE_FALLBACK 231 namespace threading {
246 explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) {
253 return lock_.native_handle();
262 class NLIB_SCOPED_CAPABILITY ScopedLock<SimpleCriticalSection> {
266 explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) {
272 ~ScopedLock()
NLIB_NOEXCEPT NLIB_RELEASE(lock_) { lock_.unlock(); }
273 native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
274 return lock_.native_handle();
283 class NLIB_SCOPED_CAPABILITY ScopedLock<nlib_mutex> {
287 explicit ScopedLock(mutex_type& m) NLIB_ACQUIRE(lock_) : lock_(m) {
290 NLIB_ASSERT_NOERR(e);
298 NLIB_ASSERT_NOERR(e);
300 native_handle_type native_handle() NLIB_RETURN_CAPABILITY(lock_) {
return &lock_; }
314 locker_(&rhs), is_locked_(true) {
318 NLIB_REQUIRES(locker_) : locker_(&rhs), is_locked_(true) {}
321 : locker_(&rhs), is_locked_(false) {}
324 is_locked_(rhs.try_lock()) {}
325 NLIB_MOVE_MEMBER_HELPER_2(
UniqueLock, locker_, is_locked_)
327 if (is_locked_) locker_->unlock();
331 NLIB_ASSERT(locker_ && !is_locked_);
332 if (!locker_ || is_locked_) {
339 NLIB_ASSERT(locker_ && is_locked_);
340 if (!locker_ || !is_locked_) {
347 NLIB_ASSERT(locker_ && !is_locked_);
348 if (!locker_ || is_locked_) {
351 is_locked_ = locker_->try_lock();
356 NLIB_ASSERT(locker_ && !is_locked_);
357 if (!locker_ || is_locked_) {
360 is_locked_ = locker_->try_lock_for(timeout);
365 NLIB_ASSERT(locker_ && !is_locked_);
366 if (!locker_ || is_locked_) {
369 is_locked_ = locker_->try_lock_until(abstime);
374 swap(locker_, rhs.locker_);
375 swap(is_locked_, rhs.is_locked_);
378 mutex_type* p = locker_;
387 return locker_->native_handle();
402 return obj.native_handle();
406 NLIB_ALWAYS_INLINE nlib_mutex* GetRawMutex(nlib_mutex& obj) NLIB_RETURN_CAPABILITY(obj) {
415 #ifndef NLIB_STD_SWAP_WORKAROUND 419 NLIB_DEFINE_STD_SWAP_T_BEGIN1(threading)
420 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::UniqueLock)
421 NLIB_DEFINE_STD_SWAP_T_END1(threading)
423 #ifndef NLIB_STD_SWAP_WORKAROUND 427 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS 429 bool nlib_is_error(NLIB_NS::threading::UniqueLock<T>&) =
delete;
435 #endif // INCLUDE_NN_NLIB_THREADING_CRITICALSECTION_H_
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_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
#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...
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.
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.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a lock, and attempts to enter the critical section.
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 ...
The class for representing the date and time.
void swap(UniqueLock &rhs) noexcept
Attempts to swap the associated CriticalSection or other object.
native_handle_type native_handle() NLIB_RETURN_CAPABILITY(*locker_)
Returns an implementation-specific handle representing a lock.
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.
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.
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.
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.
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.
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.
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.
ScopedLock(mutex_type &m, AdoptLockType) noexcept NLIB_ACQUIRE(lock_)
Assumes an object like CriticalSection is already locked, and initializes the object without locking ...
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Attempts to lock the associated object like CriticalSection.