27#ifndef MINGW_SHARED_MUTEX_H_
28#define MINGW_SHARED_MUTEX_H_
30#if !defined(__cplusplus) || (__cplusplus < 201103L)
31#error A C++11 compiler is required!
39#if (__cplusplus >= 201402L)
40#include <shared_mutex>
47#include <system_error>
87 assert(
mCounter.load(std::memory_order_relaxed) == 0);
99 using namespace this_thread;
101 expected =
mCounter.load(std::memory_order_relaxed);
104 if (
mCounter.compare_exchange_weak(expected, expected + 1,
105 std::memory_order_acquire,
106 std::memory_order_relaxed))
118 return mCounter.compare_exchange_strong( expected, expected + 1,
119 std::memory_order_acquire,
120 std::memory_order_relaxed);
128 throw system_error(make_error_code(errc::operation_not_permitted));
130 mCounter.fetch_sub(1, memory_order_release);
138 using namespace this_thread;
148 current =
mCounter.load(std::memory_order_acquire);
156 std::memory_order_acquire,
157 std::memory_order_relaxed);
165 throw system_error(make_error_code(errc::operation_not_permitted));
167 mCounter.store(0, memory_order_release);
183#if defined(_WIN32) && (WINVER >= _WIN32_WINNT_VISTA)
190 typedef PSRWLOCK native_handle_type;
193 : mHandle(SRWLOCK_INIT)
206 AcquireSRWLockExclusive(&mHandle);
209 void lock_shared (
void)
211 AcquireSRWLockShared(&mHandle);
214 void unlock_shared (
void)
216 ReleaseSRWLockShared(&mHandle);
221 ReleaseSRWLockExclusive(&mHandle);
225#if (WINVER >= _WIN32_WINNT_WIN7)
226 bool try_lock_shared (
void)
228 return TryAcquireSRWLockShared(&mHandle) != 0;
233 return TryAcquireSRWLockExclusive(&mHandle) != 0;
237 native_handle_type native_handle (
void)
245#if (defined(_WIN32) && (WINVER >= _WIN32_WINNT_WIN7))
246using windows7::shared_mutex;
248using portable::shared_mutex;
262 template<
class Clock,
class Duration >
270 while (std::chrono::steady_clock::now() < cutoff);
274 template<
class Rep,
class Period >
277 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
280 template<
class Clock,
class Duration >
288 while (std::chrono::steady_clock::now() < cutoff);
292 template<
class Rep,
class Period >
299#if __cplusplus >= 201402L
314 throw system_error(make_error_code(errc::operation_not_permitted));
316 throw system_error(make_error_code(errc::resource_deadlock_would_occur));
329 other.mMutex =
nullptr;
354 template<
class Rep,
class Period >
356 :
mMutex(&m),
mOwns(m.try_lock_shared_for(timeout_duration))
360 template<
class Clock,
class Duration >
362 :
mMutex(&m),
mOwns(m.try_lock_shared_until(timeout_time))
374 other.mMutex =
nullptr;
405 template<
class Clock,
class Duration >
415 while (std::chrono::steady_clock::now() < cutoff);
419 template<
class Rep,
class Period >
422 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
429 throw system_error(make_error_code(errc::operation_not_permitted));
460 explicit operator bool () const noexcept
466template<
class Mutex >
481#if (__cplusplus < 201703L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS))
484#if (__cplusplus < 201402L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS))
487#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING)
488#define MINGW_STDTHREAD_REDUNDANCY_WARNING
489#pragma message "This version of MinGW seems to include a win32 port of\
490 pthreads, and probably already has C++ std threading classes implemented,\
491 based on pthreads. These classes, found in namespace std, are not overridden\
492 by the mingw-std-thread library. If you would still like to use this\
493 implementation (as it is more lightweight), use the classes provided in\
494 namespace mingw_stdthread."
shared_mutex * native_handle_type
native_handle_type native_handle(void)
std::atomic< counter_type > mCounter
uint_fast16_t counter_type
shared_mutex & operator=(const shared_mutex &)=delete
bool try_lock_shared(void)
static constexpr counter_type kWriteBit
shared_mutex(const shared_mutex &)=delete
shared_lock(mutex_type &m, defer_lock_t) noexcept
shared_lock(void) noexcept
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &cutoff)
shared_lock(const shared_lock< Mutex > &)=delete
shared_lock(mutex_type &m)
shared_lock(mutex_type &m, const std::chrono::time_point< Clock, Duration > &timeout_time)
bool owns_lock(void) const noexcept
shared_lock(shared_lock< Mutex > &&other) noexcept
shared_lock(mutex_type &m, const std::chrono::duration< Rep, Period > &timeout_duration)
void verify_lockable(void)
bool try_lock_for(const std::chrono::duration< Rep, Period > &rel_time)
shared_lock(mutex_type &m, adopt_lock_t)
mutex_type * release(void) noexcept
shared_lock(mutex_type &m, try_to_lock_t)
void swap(shared_lock< Mutex > &other) noexcept
mutex_type * mutex(void) const noexcept
shared_lock & operator=(shared_lock< Mutex > &&other) noexcept
bool try_lock_for(const std::chrono::duration< Rep, Period > &rel_time)
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &cutoff)
bool try_lock_shared_for(const std::chrono::duration< Rep, Period > &rel_time)
bool try_lock_shared(void)
bool try_lock_shared_until(const std::chrono::time_point< Clock, Duration > &cutoff)
std::mutex et al implementation for MinGW (c) 2013-2016 by Mega Limited, Auckland,...
std::thread implementation for MinGW (c) 2013-2016 by Mega Limited, Auckland, New Zealand
T * ptr(T &obj)
returns a pointer (transforms reference into pointer)
void swap(shared_lock< Mutex > &lhs, shared_lock< Mutex > &rhs) noexcept
Provides common mathematical functions and vector operations.