summaryrefslogtreecommitdiff
path: root/include/shared_mutex
diff options
context:
space:
mode:
Diffstat (limited to 'include/shared_mutex')
-rw-r--r--include/shared_mutex112
1 files changed, 94 insertions, 18 deletions
diff --git a/include/shared_mutex b/include/shared_mutex
index 9b7f0bf773546..dcb93949e30d3 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -19,6 +19,29 @@
namespace std
{
+class shared_mutex // C++17
+{
+public:
+ shared_mutex();
+ ~shared_mutex();
+
+ shared_mutex(const shared_mutex&) = delete;
+ shared_mutex& operator=(const shared_mutex&) = delete;
+
+ // Exclusive ownership
+ void lock(); // blocking
+ bool try_lock();
+ void unlock();
+
+ // Shared ownership
+ void lock_shared(); // blocking
+ bool try_lock_shared();
+ void unlock_shared();
+
+ typedef implementation-defined native_handle_type; // See 30.2.3
+ native_handle_type native_handle(); // See 30.2.3
+};
+
class shared_timed_mutex
{
public:
@@ -118,7 +141,7 @@ template <class Mutex>
_LIBCPP_BEGIN_NAMESPACE_STD
-class _LIBCPP_TYPE_VIS shared_timed_mutex
+struct _LIBCPP_TYPE_VIS __shared_mutex_base
{
mutex __mut_;
condition_variable __gate1_;
@@ -127,6 +150,58 @@ class _LIBCPP_TYPE_VIS shared_timed_mutex
static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
static const unsigned __n_readers_ = ~__write_entered_;
+
+ __shared_mutex_base();
+ _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;
+
+ __shared_mutex_base(const __shared_mutex_base&) = delete;
+ __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
+
+ // Exclusive ownership
+ void lock(); // blocking
+ bool try_lock();
+ void unlock();
+
+ // Shared ownership
+ void lock_shared(); // blocking
+ bool try_lock_shared();
+ void unlock_shared();
+
+// typedef implementation-defined native_handle_type; // See 30.2.3
+// native_handle_type native_handle(); // See 30.2.3
+};
+
+
+#if _LIBCPP_STD_VER > 14
+class _LIBCPP_TYPE_VIS shared_mutex
+{
+ __shared_mutex_base __base;
+public:
+ shared_mutex() : __base() {}
+ _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
+
+ shared_mutex(const shared_mutex&) = delete;
+ shared_mutex& operator=(const shared_mutex&) = delete;
+
+ // Exclusive ownership
+ _LIBCPP_INLINE_VISIBILITY void lock() { return __base.lock(); }
+ _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); }
+ _LIBCPP_INLINE_VISIBILITY void unlock() { return __base.unlock(); }
+
+ // Shared ownership
+ _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base.lock_shared(); }
+ _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); }
+ _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base.unlock_shared(); }
+
+// typedef __shared_mutex_base::native_handle_type native_handle_type;
+// _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }
+};
+#endif
+
+
+class _LIBCPP_TYPE_VIS shared_timed_mutex
+{
+ __shared_mutex_base __base;
public:
shared_timed_mutex();
_LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
@@ -170,29 +245,30 @@ bool
shared_timed_mutex::try_lock_until(
const chrono::time_point<_Clock, _Duration>& __abs_time)
{
- unique_lock<mutex> __lk(__mut_);
- if (__state_ & __write_entered_)
+ unique_lock<mutex> __lk(__base.__mut_);
+ if (__base.__state_ & __base.__write_entered_)
{
while (true)
{
- cv_status __status = __gate1_.wait_until(__lk, __abs_time);
- if ((__state_ & __write_entered_) == 0)
+ cv_status __status = __base.__gate1_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__write_entered_) == 0)
break;
if (__status == cv_status::timeout)
return false;
}
}
- __state_ |= __write_entered_;
- if (__state_ & __n_readers_)
+ __base.__state_ |= __base.__write_entered_;
+ if (__base.__state_ & __base.__n_readers_)
{
while (true)
{
- cv_status __status = __gate2_.wait_until(__lk, __abs_time);
- if ((__state_ & __n_readers_) == 0)
+ cv_status __status = __base.__gate2_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__n_readers_) == 0)
break;
if (__status == cv_status::timeout)
{
- __state_ &= ~__write_entered_;
+ __base.__state_ &= ~__base.__write_entered_;
+ __base.__gate1_.notify_all();
return false;
}
}
@@ -205,22 +281,22 @@ bool
shared_timed_mutex::try_lock_shared_until(
const chrono::time_point<_Clock, _Duration>& __abs_time)
{
- unique_lock<mutex> __lk(__mut_);
- if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+ unique_lock<mutex> __lk(__base.__mut_);
+ if ((__base.__state_ & __base.__write_entered_) || (__base.__state_ & __base.__n_readers_) == __base.__n_readers_)
{
while (true)
{
- cv_status status = __gate1_.wait_until(__lk, __abs_time);
- if ((__state_ & __write_entered_) == 0 &&
- (__state_ & __n_readers_) < __n_readers_)
+ cv_status status = __base.__gate1_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__write_entered_) == 0 &&
+ (__base.__state_ & __base.__n_readers_) < __base.__n_readers_)
break;
if (status == cv_status::timeout)
return false;
}
}
- unsigned __num_readers = (__state_ & __n_readers_) + 1;
- __state_ &= ~__n_readers_;
- __state_ |= __num_readers;
+ unsigned __num_readers = (__base.__state_ & __base.__n_readers_) + 1;
+ __base.__state_ &= ~__base.__n_readers_;
+ __base.__state_ |= __num_readers;
return true;
}