1ead6f169SHoward Hinnant// -*- C++ -*- 2ead6f169SHoward Hinnant//===------------------------ shared_mutex --------------------------------===// 3ead6f169SHoward Hinnant// 4ead6f169SHoward Hinnant// The LLVM Compiler Infrastructure 5ead6f169SHoward Hinnant// 6ead6f169SHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 7ead6f169SHoward Hinnant// Source Licenses. See LICENSE.TXT for details. 8ead6f169SHoward Hinnant// 9ead6f169SHoward Hinnant//===----------------------------------------------------------------------===// 10ead6f169SHoward Hinnant 11ead6f169SHoward Hinnant#ifndef _LIBCPP_SHARED_MUTEX 12ead6f169SHoward Hinnant#define _LIBCPP_SHARED_MUTEX 13ead6f169SHoward Hinnant 14ead6f169SHoward Hinnant/* 15ead6f169SHoward Hinnant shared_mutex synopsis 16ead6f169SHoward Hinnant 17ead6f169SHoward Hinnant// C++1y 18ead6f169SHoward Hinnant 19ead6f169SHoward Hinnantnamespace std 20ead6f169SHoward Hinnant{ 21ead6f169SHoward Hinnant 227ec93f9bSDavid Majnemerclass shared_timed_mutex 23ead6f169SHoward Hinnant{ 24ead6f169SHoward Hinnantpublic: 257ec93f9bSDavid Majnemer shared_timed_mutex(); 267ec93f9bSDavid Majnemer ~shared_timed_mutex(); 27ead6f169SHoward Hinnant 287ec93f9bSDavid Majnemer shared_timed_mutex(const shared_timed_mutex&) = delete; 297ec93f9bSDavid Majnemer shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; 30ead6f169SHoward Hinnant 31ead6f169SHoward Hinnant // Exclusive ownership 32ead6f169SHoward Hinnant void lock(); // blocking 33ead6f169SHoward Hinnant bool try_lock(); 34ead6f169SHoward Hinnant template <class Rep, class Period> 35ead6f169SHoward Hinnant bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 36ead6f169SHoward Hinnant template <class Clock, class Duration> 37ead6f169SHoward Hinnant bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 38ead6f169SHoward Hinnant void unlock(); 39ead6f169SHoward Hinnant 40ead6f169SHoward Hinnant // Shared ownership 41ead6f169SHoward Hinnant void lock_shared(); // blocking 42ead6f169SHoward Hinnant bool try_lock_shared(); 43ead6f169SHoward Hinnant template <class Rep, class Period> 44ead6f169SHoward Hinnant bool 45ead6f169SHoward Hinnant try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time); 46ead6f169SHoward Hinnant template <class Clock, class Duration> 47ead6f169SHoward Hinnant bool 48ead6f169SHoward Hinnant try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time); 49ead6f169SHoward Hinnant void unlock_shared(); 50ead6f169SHoward Hinnant}; 51ead6f169SHoward Hinnant 52ead6f169SHoward Hinnanttemplate <class Mutex> 53ead6f169SHoward Hinnantclass shared_lock 54ead6f169SHoward Hinnant{ 55ead6f169SHoward Hinnantpublic: 56ead6f169SHoward Hinnant typedef Mutex mutex_type; 57ead6f169SHoward Hinnant 58ead6f169SHoward Hinnant // Shared locking 59ead6f169SHoward Hinnant shared_lock() noexcept; 60ead6f169SHoward Hinnant explicit shared_lock(mutex_type& m); // blocking 61ead6f169SHoward Hinnant shared_lock(mutex_type& m, defer_lock_t) noexcept; 62ead6f169SHoward Hinnant shared_lock(mutex_type& m, try_to_lock_t); 63ead6f169SHoward Hinnant shared_lock(mutex_type& m, adopt_lock_t); 64ead6f169SHoward Hinnant template <class Clock, class Duration> 65ead6f169SHoward Hinnant shared_lock(mutex_type& m, 66ead6f169SHoward Hinnant const chrono::time_point<Clock, Duration>& abs_time); 67ead6f169SHoward Hinnant template <class Rep, class Period> 68ead6f169SHoward Hinnant shared_lock(mutex_type& m, 69ead6f169SHoward Hinnant const chrono::duration<Rep, Period>& rel_time); 70ead6f169SHoward Hinnant ~shared_lock(); 71ead6f169SHoward Hinnant 72ead6f169SHoward Hinnant shared_lock(shared_lock const&) = delete; 73ead6f169SHoward Hinnant shared_lock& operator=(shared_lock const&) = delete; 74ead6f169SHoward Hinnant 75ead6f169SHoward Hinnant shared_lock(shared_lock&& u) noexcept; 76ead6f169SHoward Hinnant shared_lock& operator=(shared_lock&& u) noexcept; 77ead6f169SHoward Hinnant 78ead6f169SHoward Hinnant void lock(); // blocking 79ead6f169SHoward Hinnant bool try_lock(); 80ead6f169SHoward Hinnant template <class Rep, class Period> 81ead6f169SHoward Hinnant bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 82ead6f169SHoward Hinnant template <class Clock, class Duration> 83ead6f169SHoward Hinnant bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 84ead6f169SHoward Hinnant void unlock(); 85ead6f169SHoward Hinnant 86ead6f169SHoward Hinnant // Setters 87ead6f169SHoward Hinnant void swap(shared_lock& u) noexcept; 88ead6f169SHoward Hinnant mutex_type* release() noexcept; 89ead6f169SHoward Hinnant 90ead6f169SHoward Hinnant // Getters 91ead6f169SHoward Hinnant bool owns_lock() const noexcept; 92ead6f169SHoward Hinnant explicit operator bool () const noexcept; 93ead6f169SHoward Hinnant mutex_type* mutex() const noexcept; 94ead6f169SHoward Hinnant}; 95ead6f169SHoward Hinnant 96ead6f169SHoward Hinnanttemplate <class Mutex> 97ead6f169SHoward Hinnant void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept; 98ead6f169SHoward Hinnant 99ead6f169SHoward Hinnant} // std 100ead6f169SHoward Hinnant 101ead6f169SHoward Hinnant*/ 102ead6f169SHoward Hinnant 103ead6f169SHoward Hinnant#include <__config> 104ead6f169SHoward Hinnant 105ead6f169SHoward Hinnant#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX) 106ead6f169SHoward Hinnant 107ead6f169SHoward Hinnant#include <__mutex_base> 108ead6f169SHoward Hinnant 109ead6f169SHoward Hinnant#include <__undef_min_max> 110ead6f169SHoward Hinnant 111ead6f169SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 112ead6f169SHoward Hinnant#pragma GCC system_header 113ead6f169SHoward Hinnant#endif 114ead6f169SHoward Hinnant 115*b3fcc67fSJonathan Roelofs#ifdef _LIBCPP_HAS_NO_THREADS 116*b3fcc67fSJonathan Roelofs#error <shared_mutex> is not supported on this single threaded system 117*b3fcc67fSJonathan Roelofs#else // !_LIBCPP_HAS_NO_THREADS 118*b3fcc67fSJonathan Roelofs 119ead6f169SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 120ead6f169SHoward Hinnant 1217ec93f9bSDavid Majnemerclass _LIBCPP_TYPE_VIS shared_timed_mutex 122ead6f169SHoward Hinnant{ 123ead6f169SHoward Hinnant mutex __mut_; 124ead6f169SHoward Hinnant condition_variable __gate1_; 125ead6f169SHoward Hinnant condition_variable __gate2_; 126ead6f169SHoward Hinnant unsigned __state_; 127ead6f169SHoward Hinnant 128ead6f169SHoward Hinnant static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); 129ead6f169SHoward Hinnant static const unsigned __n_readers_ = ~__write_entered_; 130ead6f169SHoward Hinnantpublic: 1317ec93f9bSDavid Majnemer shared_timed_mutex(); 1327ec93f9bSDavid Majnemer _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default; 133ead6f169SHoward Hinnant 1347ec93f9bSDavid Majnemer shared_timed_mutex(const shared_timed_mutex&) = delete; 1357ec93f9bSDavid Majnemer shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; 136ead6f169SHoward Hinnant 137ead6f169SHoward Hinnant // Exclusive ownership 138ead6f169SHoward Hinnant void lock(); 139ead6f169SHoward Hinnant bool try_lock(); 140ead6f169SHoward Hinnant template <class _Rep, class _Period> 141ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 142ead6f169SHoward Hinnant bool 143ead6f169SHoward Hinnant try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) 144ead6f169SHoward Hinnant { 145ead6f169SHoward Hinnant return try_lock_until(chrono::steady_clock::now() + __rel_time); 146ead6f169SHoward Hinnant } 147ead6f169SHoward Hinnant template <class _Clock, class _Duration> 148ead6f169SHoward Hinnant bool 149ead6f169SHoward Hinnant try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time); 150ead6f169SHoward Hinnant void unlock(); 151ead6f169SHoward Hinnant 152ead6f169SHoward Hinnant // Shared ownership 153ead6f169SHoward Hinnant void lock_shared(); 154ead6f169SHoward Hinnant bool try_lock_shared(); 155ead6f169SHoward Hinnant template <class _Rep, class _Period> 156ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 157ead6f169SHoward Hinnant bool 158ead6f169SHoward Hinnant try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) 159ead6f169SHoward Hinnant { 160ead6f169SHoward Hinnant return try_lock_shared_until(chrono::steady_clock::now() + __rel_time); 161ead6f169SHoward Hinnant } 162ead6f169SHoward Hinnant template <class _Clock, class _Duration> 163ead6f169SHoward Hinnant bool 164ead6f169SHoward Hinnant try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time); 165ead6f169SHoward Hinnant void unlock_shared(); 166ead6f169SHoward Hinnant}; 167ead6f169SHoward Hinnant 168ead6f169SHoward Hinnanttemplate <class _Clock, class _Duration> 169ead6f169SHoward Hinnantbool 1707ec93f9bSDavid Majnemershared_timed_mutex::try_lock_until( 171ead6f169SHoward Hinnant const chrono::time_point<_Clock, _Duration>& __abs_time) 172ead6f169SHoward Hinnant{ 173ead6f169SHoward Hinnant unique_lock<mutex> __lk(__mut_); 174ead6f169SHoward Hinnant if (__state_ & __write_entered_) 175ead6f169SHoward Hinnant { 176ead6f169SHoward Hinnant while (true) 177ead6f169SHoward Hinnant { 178ead6f169SHoward Hinnant cv_status __status = __gate1_.wait_until(__lk, __abs_time); 179ead6f169SHoward Hinnant if ((__state_ & __write_entered_) == 0) 180ead6f169SHoward Hinnant break; 181ead6f169SHoward Hinnant if (__status == cv_status::timeout) 182ead6f169SHoward Hinnant return false; 183ead6f169SHoward Hinnant } 184ead6f169SHoward Hinnant } 185ead6f169SHoward Hinnant __state_ |= __write_entered_; 186ead6f169SHoward Hinnant if (__state_ & __n_readers_) 187ead6f169SHoward Hinnant { 188ead6f169SHoward Hinnant while (true) 189ead6f169SHoward Hinnant { 190ead6f169SHoward Hinnant cv_status __status = __gate2_.wait_until(__lk, __abs_time); 191ead6f169SHoward Hinnant if ((__state_ & __n_readers_) == 0) 192ead6f169SHoward Hinnant break; 193ead6f169SHoward Hinnant if (__status == cv_status::timeout) 194ead6f169SHoward Hinnant { 195ead6f169SHoward Hinnant __state_ &= ~__write_entered_; 196ead6f169SHoward Hinnant return false; 197ead6f169SHoward Hinnant } 198ead6f169SHoward Hinnant } 199ead6f169SHoward Hinnant } 200ead6f169SHoward Hinnant return true; 201ead6f169SHoward Hinnant} 202ead6f169SHoward Hinnant 203ead6f169SHoward Hinnanttemplate <class _Clock, class _Duration> 204ead6f169SHoward Hinnantbool 2057ec93f9bSDavid Majnemershared_timed_mutex::try_lock_shared_until( 206ead6f169SHoward Hinnant const chrono::time_point<_Clock, _Duration>& __abs_time) 207ead6f169SHoward Hinnant{ 208ead6f169SHoward Hinnant unique_lock<mutex> __lk(__mut_); 209ead6f169SHoward Hinnant if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) 210ead6f169SHoward Hinnant { 211ead6f169SHoward Hinnant while (true) 212ead6f169SHoward Hinnant { 213ead6f169SHoward Hinnant cv_status status = __gate1_.wait_until(__lk, __abs_time); 214ead6f169SHoward Hinnant if ((__state_ & __write_entered_) == 0 && 215ead6f169SHoward Hinnant (__state_ & __n_readers_) < __n_readers_) 216ead6f169SHoward Hinnant break; 217ead6f169SHoward Hinnant if (status == cv_status::timeout) 218ead6f169SHoward Hinnant return false; 219ead6f169SHoward Hinnant } 220ead6f169SHoward Hinnant } 221ead6f169SHoward Hinnant unsigned __num_readers = (__state_ & __n_readers_) + 1; 222ead6f169SHoward Hinnant __state_ &= ~__n_readers_; 223ead6f169SHoward Hinnant __state_ |= __num_readers; 224ead6f169SHoward Hinnant return true; 225ead6f169SHoward Hinnant} 226ead6f169SHoward Hinnant 227ead6f169SHoward Hinnanttemplate <class _Mutex> 228ead6f169SHoward Hinnantclass shared_lock 229ead6f169SHoward Hinnant{ 230ead6f169SHoward Hinnantpublic: 231ead6f169SHoward Hinnant typedef _Mutex mutex_type; 232ead6f169SHoward Hinnant 233ead6f169SHoward Hinnantprivate: 234ead6f169SHoward Hinnant mutex_type* __m_; 235ead6f169SHoward Hinnant bool __owns_; 236ead6f169SHoward Hinnant 237ead6f169SHoward Hinnantpublic: 238ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 239d08f0d9cSMarshall Clow shared_lock() _NOEXCEPT 240ead6f169SHoward Hinnant : __m_(nullptr), 241ead6f169SHoward Hinnant __owns_(false) 242ead6f169SHoward Hinnant {} 243ead6f169SHoward Hinnant 244ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 245ead6f169SHoward Hinnant explicit shared_lock(mutex_type& __m) 246ead6f169SHoward Hinnant : __m_(&__m), 247ead6f169SHoward Hinnant __owns_(true) 248ead6f169SHoward Hinnant {__m_->lock_shared();} 249ead6f169SHoward Hinnant 250ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 251d08f0d9cSMarshall Clow shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT 252ead6f169SHoward Hinnant : __m_(&__m), 253ead6f169SHoward Hinnant __owns_(false) 254ead6f169SHoward Hinnant {} 255ead6f169SHoward Hinnant 256ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 257ead6f169SHoward Hinnant shared_lock(mutex_type& __m, try_to_lock_t) 258ead6f169SHoward Hinnant : __m_(&__m), 259ead6f169SHoward Hinnant __owns_(__m.try_lock_shared()) 260ead6f169SHoward Hinnant {} 261ead6f169SHoward Hinnant 262ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 263ead6f169SHoward Hinnant shared_lock(mutex_type& __m, adopt_lock_t) 264ead6f169SHoward Hinnant : __m_(&__m), 265ead6f169SHoward Hinnant __owns_(true) 266ead6f169SHoward Hinnant {} 267ead6f169SHoward Hinnant 268ead6f169SHoward Hinnant template <class _Clock, class _Duration> 269ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 270ead6f169SHoward Hinnant shared_lock(mutex_type& __m, 271ead6f169SHoward Hinnant const chrono::time_point<_Clock, _Duration>& __abs_time) 272ead6f169SHoward Hinnant : __m_(&__m), 273ead6f169SHoward Hinnant __owns_(__m.try_lock_shared_until(__abs_time)) 274ead6f169SHoward Hinnant {} 275ead6f169SHoward Hinnant 276ead6f169SHoward Hinnant template <class _Rep, class _Period> 277ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 278ead6f169SHoward Hinnant shared_lock(mutex_type& __m, 279ead6f169SHoward Hinnant const chrono::duration<_Rep, _Period>& __rel_time) 280ead6f169SHoward Hinnant : __m_(&__m), 281ead6f169SHoward Hinnant __owns_(__m.try_lock_shared_for(__rel_time)) 282ead6f169SHoward Hinnant {} 283ead6f169SHoward Hinnant 284ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 285ead6f169SHoward Hinnant ~shared_lock() 286ead6f169SHoward Hinnant { 287ead6f169SHoward Hinnant if (__owns_) 288ead6f169SHoward Hinnant __m_->unlock_shared(); 289ead6f169SHoward Hinnant } 290ead6f169SHoward Hinnant 291ead6f169SHoward Hinnant shared_lock(shared_lock const&) = delete; 292ead6f169SHoward Hinnant shared_lock& operator=(shared_lock const&) = delete; 293ead6f169SHoward Hinnant 294ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 295d08f0d9cSMarshall Clow shared_lock(shared_lock&& __u) _NOEXCEPT 296ead6f169SHoward Hinnant : __m_(__u.__m_), 297ead6f169SHoward Hinnant __owns_(__u.__owns_) 298ead6f169SHoward Hinnant { 299ead6f169SHoward Hinnant __u.__m_ = nullptr; 300ead6f169SHoward Hinnant __u.__owns_ = false; 301ead6f169SHoward Hinnant } 302ead6f169SHoward Hinnant 303ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 304d08f0d9cSMarshall Clow shared_lock& operator=(shared_lock&& __u) _NOEXCEPT 305ead6f169SHoward Hinnant { 306ead6f169SHoward Hinnant if (__owns_) 307ead6f169SHoward Hinnant __m_->unlock_shared(); 308ead6f169SHoward Hinnant __m_ = nullptr; 309ead6f169SHoward Hinnant __owns_ = false; 310ead6f169SHoward Hinnant __m_ = __u.__m_; 311ead6f169SHoward Hinnant __owns_ = __u.__owns_; 312ead6f169SHoward Hinnant __u.__m_ = nullptr; 313ead6f169SHoward Hinnant __u.__owns_ = false; 314ead6f169SHoward Hinnant return *this; 315ead6f169SHoward Hinnant } 316ead6f169SHoward Hinnant 317ead6f169SHoward Hinnant void lock(); 318ead6f169SHoward Hinnant bool try_lock(); 319ead6f169SHoward Hinnant template <class Rep, class Period> 320ead6f169SHoward Hinnant bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 321ead6f169SHoward Hinnant template <class Clock, class Duration> 322ead6f169SHoward Hinnant bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 323ead6f169SHoward Hinnant void unlock(); 324ead6f169SHoward Hinnant 325ead6f169SHoward Hinnant // Setters 326ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 327d08f0d9cSMarshall Clow void swap(shared_lock& __u) _NOEXCEPT 328ead6f169SHoward Hinnant { 329ead6f169SHoward Hinnant _VSTD::swap(__m_, __u.__m_); 330ead6f169SHoward Hinnant _VSTD::swap(__owns_, __u.__owns_); 331ead6f169SHoward Hinnant } 332ead6f169SHoward Hinnant 333ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 334d08f0d9cSMarshall Clow mutex_type* release() _NOEXCEPT 335ead6f169SHoward Hinnant { 336ead6f169SHoward Hinnant mutex_type* __m = __m_; 337ead6f169SHoward Hinnant __m_ = nullptr; 338ead6f169SHoward Hinnant __owns_ = false; 339ead6f169SHoward Hinnant return __m; 340ead6f169SHoward Hinnant } 341ead6f169SHoward Hinnant 342ead6f169SHoward Hinnant // Getters 343ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 344d08f0d9cSMarshall Clow bool owns_lock() const _NOEXCEPT {return __owns_;} 345ead6f169SHoward Hinnant 346ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 347d08f0d9cSMarshall Clow explicit operator bool () const _NOEXCEPT {return __owns_;} 348ead6f169SHoward Hinnant 349ead6f169SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 350d08f0d9cSMarshall Clow mutex_type* mutex() const _NOEXCEPT {return __m_;} 351ead6f169SHoward Hinnant}; 352ead6f169SHoward Hinnant 353ead6f169SHoward Hinnanttemplate <class _Mutex> 354ead6f169SHoward Hinnantvoid 355ead6f169SHoward Hinnantshared_lock<_Mutex>::lock() 356ead6f169SHoward Hinnant{ 357ead6f169SHoward Hinnant if (__m_ == nullptr) 358ead6f169SHoward Hinnant __throw_system_error(EPERM, "shared_lock::lock: references null mutex"); 359ead6f169SHoward Hinnant if (__owns_) 360ead6f169SHoward Hinnant __throw_system_error(EDEADLK, "shared_lock::lock: already locked"); 361ead6f169SHoward Hinnant __m_->lock_shared(); 362ead6f169SHoward Hinnant __owns_ = true; 363ead6f169SHoward Hinnant} 364ead6f169SHoward Hinnant 365ead6f169SHoward Hinnanttemplate <class _Mutex> 366ead6f169SHoward Hinnantbool 367ead6f169SHoward Hinnantshared_lock<_Mutex>::try_lock() 368ead6f169SHoward Hinnant{ 369ead6f169SHoward Hinnant if (__m_ == nullptr) 370ead6f169SHoward Hinnant __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex"); 371ead6f169SHoward Hinnant if (__owns_) 372ead6f169SHoward Hinnant __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked"); 373ead6f169SHoward Hinnant __owns_ = __m_->try_lock_shared(); 374ead6f169SHoward Hinnant return __owns_; 375ead6f169SHoward Hinnant} 376ead6f169SHoward Hinnant 377ead6f169SHoward Hinnanttemplate <class _Mutex> 378ead6f169SHoward Hinnanttemplate <class _Rep, class _Period> 379ead6f169SHoward Hinnantbool 380ead6f169SHoward Hinnantshared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) 381ead6f169SHoward Hinnant{ 382ead6f169SHoward Hinnant if (__m_ == nullptr) 383ead6f169SHoward Hinnant __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex"); 384ead6f169SHoward Hinnant if (__owns_) 385ead6f169SHoward Hinnant __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked"); 386ead6f169SHoward Hinnant __owns_ = __m_->try_lock_shared_for(__d); 387ead6f169SHoward Hinnant return __owns_; 388ead6f169SHoward Hinnant} 389ead6f169SHoward Hinnant 390ead6f169SHoward Hinnanttemplate <class _Mutex> 391ead6f169SHoward Hinnanttemplate <class _Clock, class _Duration> 392ead6f169SHoward Hinnantbool 393ead6f169SHoward Hinnantshared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 394ead6f169SHoward Hinnant{ 395ead6f169SHoward Hinnant if (__m_ == nullptr) 396ead6f169SHoward Hinnant __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex"); 397ead6f169SHoward Hinnant if (__owns_) 398ead6f169SHoward Hinnant __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked"); 399ead6f169SHoward Hinnant __owns_ = __m_->try_lock_shared_until(__t); 400ead6f169SHoward Hinnant return __owns_; 401ead6f169SHoward Hinnant} 402ead6f169SHoward Hinnant 403ead6f169SHoward Hinnanttemplate <class _Mutex> 404ead6f169SHoward Hinnantvoid 405ead6f169SHoward Hinnantshared_lock<_Mutex>::unlock() 406ead6f169SHoward Hinnant{ 407ead6f169SHoward Hinnant if (!__owns_) 408ead6f169SHoward Hinnant __throw_system_error(EPERM, "shared_lock::unlock: not locked"); 409ead6f169SHoward Hinnant __m_->unlock_shared(); 410ead6f169SHoward Hinnant __owns_ = false; 411ead6f169SHoward Hinnant} 412ead6f169SHoward Hinnant 413ead6f169SHoward Hinnanttemplate <class _Mutex> 414ead6f169SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 415ead6f169SHoward Hinnantvoid 416d08f0d9cSMarshall Clowswap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT 417ead6f169SHoward Hinnant {__x.swap(__y);} 418ead6f169SHoward Hinnant 419ead6f169SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 420ead6f169SHoward Hinnant 421*b3fcc67fSJonathan Roelofs#endif // !_LIBCPP_HAS_NO_THREADS 422*b3fcc67fSJonathan Roelofs 423ead6f169SHoward Hinnant#endif // _LIBCPP_STD_VER > 11 424ead6f169SHoward Hinnant 425ead6f169SHoward Hinnant#endif // _LIBCPP_SHARED_MUTEX 426