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
Defines noexcept geared to the environment, or the equivalent.
UniqueLock() noexcept
Initializes an object without creating an association.
native_handle_type native_handle() noexcept
Gets a pointer to a native type mutex.
bool owns_lock() const noexcept
Returns true if the lock associated with UniqueLock is locked.
void lock() noexcept
Gets a lock, and enters the critical section. Blocks until it can get a lock.
~ScopedLock() noexcept NLIB_UNLOCK_FUNC(m_Lock)
Unlocks objects like CriticalSection (calls unlock).
#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...
bool try_lock() noexcept NLIB_TRYLOCK_FUNC(true)
Gets a lock, and attempts to enter the critical section.
Simplest critical section. Not reentrant.
mutex_type * release() noexcept
Removes the association. Does not unlock.
ScopedLock(mutex_type &m, AdoptLockType) noexcept NLIB_LOCK_FUNC(m_Lock)
Assumes an object like CriticalSection is already locked, and initializes the object without locking ...
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type.
UniqueLock(mutex_type &rhs, AdoptLockType)
Assumes an object like CriticalSection is already locked, and initializes the object without locking ...
bool try_lock() noexcept
Attempts to lock the associated object like CriticalSection.
void unlock() noexcept
Releases the lock, and exits the critical section.
mutex_type::native_handle_type native_handle_type
mutex_type::native_handle_type.
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()
Returns an implementation-specific handle representing a lock.
constexpr SimpleCriticalSection() noexcept
Instantiates the object with default parameters (default constructor).
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
void unlock() noexcept
Releases the lock, and exits the critical section.
Used in ScopedLock and UniqueLock by tag type.
constexpr CriticalSection() noexcept
Instantiates the object with default parameters (default constructor).
void lock() noexcept NLIB_LOCK_FUNC()
Gets a lock, and enters the critical section. Blocks until it can get a lock.
Class to wrap objects like CriticalSection.
nlib_mutex * native_handle_type
typedef to a pointer type to a native mutex.
bool try_lock() noexcept
Gets a lock, and attempts to enter the critical section.
native_handle_type native_handle()
Returns an implementation-specific handle representing a lock.
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.
ScopedLock(mutex_type &m) NLIB_LOCK_FUNC(m_Lock)
Locks objects like CriticalSection (calls lock).
bool try_lock_for(const TimeSpan &timeout) noexcept
Attempts to lock with timeout the associated CriticalSection or other object.
constexpr const DeferLockType deferLock
A DeferLockType-type value.
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 lock() noexcept
Gets a lock, and enters the critical section. Blocks until it can get a lock.
UniqueLock(mutex_type &rhs, TryToLockType)
Attempts to lock using try_lock when initializing.
Wraps objects like CriticalSection. Locks with a constructor, and unlocks with a destructor.
void unlock() noexcept NLIB_UNLOCK_FUNC()
Releases the lock, and exits the critical section.
UniqueLock(mutex_type &rhs)
Locks the object like CriticalSection and associates it with this object.
The class for representing the time.
Critical section that can timeout in reentrant.
native_handle_type native_handle() noexcept
Gets a pointer to a native type mutex.
constexpr const TryToLockType tryToLock
A TryToLockType-type value.
void unlock() noexcept
Unlocks the associated CriticalSection or other object.
bool try_lock() noexcept
Gets a lock, and attempts to enter the critical section.
UniqueLock(mutex_type &rhs, DeferLockType) noexcept
Initializes an object without locking.
constexpr TimedCriticalSection() noexcept
Instantiates the object with default parameters (default constructor).
void lock()
Locks the associated CriticalSection or other object.
mutex_type * mutex() const noexcept
Gets the pointer to the associated object like CriticalSection.
bool try_lock_until(const DateTime &abstime) noexcept
Attempts to lock with timeout the associated CriticalSection or other object.
native_handle_type native_handle() noexcept
Gets a pointer to a native type mutex.