1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*- 2*58b9f456SAndroid Build Coastguard Worker//===------------------------ shared_mutex --------------------------------===// 3*58b9f456SAndroid Build Coastguard Worker// 4*58b9f456SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 5*58b9f456SAndroid Build Coastguard Worker// 6*58b9f456SAndroid Build Coastguard Worker// This file is dual licensed under the MIT and the University of Illinois Open 7*58b9f456SAndroid Build Coastguard Worker// Source Licenses. See LICENSE.TXT for details. 8*58b9f456SAndroid Build Coastguard Worker// 9*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 10*58b9f456SAndroid Build Coastguard Worker 11*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_SHARED_MUTEX 12*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_SHARED_MUTEX 13*58b9f456SAndroid Build Coastguard Worker 14*58b9f456SAndroid Build Coastguard Worker/* 15*58b9f456SAndroid Build Coastguard Worker shared_mutex synopsis 16*58b9f456SAndroid Build Coastguard Worker 17*58b9f456SAndroid Build Coastguard Worker// C++1y 18*58b9f456SAndroid Build Coastguard Worker 19*58b9f456SAndroid Build Coastguard Workernamespace std 20*58b9f456SAndroid Build Coastguard Worker{ 21*58b9f456SAndroid Build Coastguard Worker 22*58b9f456SAndroid Build Coastguard Workerclass shared_mutex // C++17 23*58b9f456SAndroid Build Coastguard Worker{ 24*58b9f456SAndroid Build Coastguard Workerpublic: 25*58b9f456SAndroid Build Coastguard Worker shared_mutex(); 26*58b9f456SAndroid Build Coastguard Worker ~shared_mutex(); 27*58b9f456SAndroid Build Coastguard Worker 28*58b9f456SAndroid Build Coastguard Worker shared_mutex(const shared_mutex&) = delete; 29*58b9f456SAndroid Build Coastguard Worker shared_mutex& operator=(const shared_mutex&) = delete; 30*58b9f456SAndroid Build Coastguard Worker 31*58b9f456SAndroid Build Coastguard Worker // Exclusive ownership 32*58b9f456SAndroid Build Coastguard Worker void lock(); // blocking 33*58b9f456SAndroid Build Coastguard Worker bool try_lock(); 34*58b9f456SAndroid Build Coastguard Worker void unlock(); 35*58b9f456SAndroid Build Coastguard Worker 36*58b9f456SAndroid Build Coastguard Worker // Shared ownership 37*58b9f456SAndroid Build Coastguard Worker void lock_shared(); // blocking 38*58b9f456SAndroid Build Coastguard Worker bool try_lock_shared(); 39*58b9f456SAndroid Build Coastguard Worker void unlock_shared(); 40*58b9f456SAndroid Build Coastguard Worker 41*58b9f456SAndroid Build Coastguard Worker typedef implementation-defined native_handle_type; // See 30.2.3 42*58b9f456SAndroid Build Coastguard Worker native_handle_type native_handle(); // See 30.2.3 43*58b9f456SAndroid Build Coastguard Worker}; 44*58b9f456SAndroid Build Coastguard Worker 45*58b9f456SAndroid Build Coastguard Workerclass shared_timed_mutex 46*58b9f456SAndroid Build Coastguard Worker{ 47*58b9f456SAndroid Build Coastguard Workerpublic: 48*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex(); 49*58b9f456SAndroid Build Coastguard Worker ~shared_timed_mutex(); 50*58b9f456SAndroid Build Coastguard Worker 51*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex(const shared_timed_mutex&) = delete; 52*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; 53*58b9f456SAndroid Build Coastguard Worker 54*58b9f456SAndroid Build Coastguard Worker // Exclusive ownership 55*58b9f456SAndroid Build Coastguard Worker void lock(); // blocking 56*58b9f456SAndroid Build Coastguard Worker bool try_lock(); 57*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 58*58b9f456SAndroid Build Coastguard Worker bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 59*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 60*58b9f456SAndroid Build Coastguard Worker bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 61*58b9f456SAndroid Build Coastguard Worker void unlock(); 62*58b9f456SAndroid Build Coastguard Worker 63*58b9f456SAndroid Build Coastguard Worker // Shared ownership 64*58b9f456SAndroid Build Coastguard Worker void lock_shared(); // blocking 65*58b9f456SAndroid Build Coastguard Worker bool try_lock_shared(); 66*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 67*58b9f456SAndroid Build Coastguard Worker bool 68*58b9f456SAndroid Build Coastguard Worker try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time); 69*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 70*58b9f456SAndroid Build Coastguard Worker bool 71*58b9f456SAndroid Build Coastguard Worker try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time); 72*58b9f456SAndroid Build Coastguard Worker void unlock_shared(); 73*58b9f456SAndroid Build Coastguard Worker}; 74*58b9f456SAndroid Build Coastguard Worker 75*58b9f456SAndroid Build Coastguard Workertemplate <class Mutex> 76*58b9f456SAndroid Build Coastguard Workerclass shared_lock 77*58b9f456SAndroid Build Coastguard Worker{ 78*58b9f456SAndroid Build Coastguard Workerpublic: 79*58b9f456SAndroid Build Coastguard Worker typedef Mutex mutex_type; 80*58b9f456SAndroid Build Coastguard Worker 81*58b9f456SAndroid Build Coastguard Worker // Shared locking 82*58b9f456SAndroid Build Coastguard Worker shared_lock() noexcept; 83*58b9f456SAndroid Build Coastguard Worker explicit shared_lock(mutex_type& m); // blocking 84*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& m, defer_lock_t) noexcept; 85*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& m, try_to_lock_t); 86*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& m, adopt_lock_t); 87*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 88*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& m, 89*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<Clock, Duration>& abs_time); 90*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 91*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& m, 92*58b9f456SAndroid Build Coastguard Worker const chrono::duration<Rep, Period>& rel_time); 93*58b9f456SAndroid Build Coastguard Worker ~shared_lock(); 94*58b9f456SAndroid Build Coastguard Worker 95*58b9f456SAndroid Build Coastguard Worker shared_lock(shared_lock const&) = delete; 96*58b9f456SAndroid Build Coastguard Worker shared_lock& operator=(shared_lock const&) = delete; 97*58b9f456SAndroid Build Coastguard Worker 98*58b9f456SAndroid Build Coastguard Worker shared_lock(shared_lock&& u) noexcept; 99*58b9f456SAndroid Build Coastguard Worker shared_lock& operator=(shared_lock&& u) noexcept; 100*58b9f456SAndroid Build Coastguard Worker 101*58b9f456SAndroid Build Coastguard Worker void lock(); // blocking 102*58b9f456SAndroid Build Coastguard Worker bool try_lock(); 103*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 104*58b9f456SAndroid Build Coastguard Worker bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 105*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 106*58b9f456SAndroid Build Coastguard Worker bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 107*58b9f456SAndroid Build Coastguard Worker void unlock(); 108*58b9f456SAndroid Build Coastguard Worker 109*58b9f456SAndroid Build Coastguard Worker // Setters 110*58b9f456SAndroid Build Coastguard Worker void swap(shared_lock& u) noexcept; 111*58b9f456SAndroid Build Coastguard Worker mutex_type* release() noexcept; 112*58b9f456SAndroid Build Coastguard Worker 113*58b9f456SAndroid Build Coastguard Worker // Getters 114*58b9f456SAndroid Build Coastguard Worker bool owns_lock() const noexcept; 115*58b9f456SAndroid Build Coastguard Worker explicit operator bool () const noexcept; 116*58b9f456SAndroid Build Coastguard Worker mutex_type* mutex() const noexcept; 117*58b9f456SAndroid Build Coastguard Worker}; 118*58b9f456SAndroid Build Coastguard Worker 119*58b9f456SAndroid Build Coastguard Workertemplate <class Mutex> 120*58b9f456SAndroid Build Coastguard Worker void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept; 121*58b9f456SAndroid Build Coastguard Worker 122*58b9f456SAndroid Build Coastguard Worker} // std 123*58b9f456SAndroid Build Coastguard Worker 124*58b9f456SAndroid Build Coastguard Worker*/ 125*58b9f456SAndroid Build Coastguard Worker 126*58b9f456SAndroid Build Coastguard Worker#include <__config> 127*58b9f456SAndroid Build Coastguard Worker#include <version> 128*58b9f456SAndroid Build Coastguard Worker 129*58b9f456SAndroid Build Coastguard Worker_LIBCPP_PUSH_MACROS 130*58b9f456SAndroid Build Coastguard Worker#include <__undef_macros> 131*58b9f456SAndroid Build Coastguard Worker 132*58b9f456SAndroid Build Coastguard Worker 133*58b9f456SAndroid Build Coastguard Worker#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY) 134*58b9f456SAndroid Build Coastguard Worker 135*58b9f456SAndroid Build Coastguard Worker#include <__mutex_base> 136*58b9f456SAndroid Build Coastguard Worker 137*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 138*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header 139*58b9f456SAndroid Build Coastguard Worker#endif 140*58b9f456SAndroid Build Coastguard Worker 141*58b9f456SAndroid Build Coastguard Worker#ifdef _LIBCPP_HAS_NO_THREADS 142*58b9f456SAndroid Build Coastguard Worker#error <shared_mutex> is not supported on this single threaded system 143*58b9f456SAndroid Build Coastguard Worker#else // !_LIBCPP_HAS_NO_THREADS 144*58b9f456SAndroid Build Coastguard Worker 145*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_STD 146*58b9f456SAndroid Build Coastguard Worker 147*58b9f456SAndroid Build Coastguard Workerstruct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex")) 148*58b9f456SAndroid Build Coastguard Worker__shared_mutex_base 149*58b9f456SAndroid Build Coastguard Worker{ 150*58b9f456SAndroid Build Coastguard Worker mutex __mut_; 151*58b9f456SAndroid Build Coastguard Worker condition_variable __gate1_; 152*58b9f456SAndroid Build Coastguard Worker condition_variable __gate2_; 153*58b9f456SAndroid Build Coastguard Worker unsigned __state_; 154*58b9f456SAndroid Build Coastguard Worker 155*58b9f456SAndroid Build Coastguard Worker static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); 156*58b9f456SAndroid Build Coastguard Worker static const unsigned __n_readers_ = ~__write_entered_; 157*58b9f456SAndroid Build Coastguard Worker 158*58b9f456SAndroid Build Coastguard Worker __shared_mutex_base(); 159*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default; 160*58b9f456SAndroid Build Coastguard Worker 161*58b9f456SAndroid Build Coastguard Worker __shared_mutex_base(const __shared_mutex_base&) = delete; 162*58b9f456SAndroid Build Coastguard Worker __shared_mutex_base& operator=(const __shared_mutex_base&) = delete; 163*58b9f456SAndroid Build Coastguard Worker 164*58b9f456SAndroid Build Coastguard Worker // Exclusive ownership 165*58b9f456SAndroid Build Coastguard Worker void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking 166*58b9f456SAndroid Build Coastguard Worker bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); 167*58b9f456SAndroid Build Coastguard Worker void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); 168*58b9f456SAndroid Build Coastguard Worker 169*58b9f456SAndroid Build Coastguard Worker // Shared ownership 170*58b9f456SAndroid Build Coastguard Worker void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking 171*58b9f456SAndroid Build Coastguard Worker bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true)); 172*58b9f456SAndroid Build Coastguard Worker void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability()); 173*58b9f456SAndroid Build Coastguard Worker 174*58b9f456SAndroid Build Coastguard Worker// typedef implementation-defined native_handle_type; // See 30.2.3 175*58b9f456SAndroid Build Coastguard Worker// native_handle_type native_handle(); // See 30.2.3 176*58b9f456SAndroid Build Coastguard Worker}; 177*58b9f456SAndroid Build Coastguard Worker 178*58b9f456SAndroid Build Coastguard Worker 179*58b9f456SAndroid Build Coastguard Worker#if _LIBCPP_STD_VER > 14 180*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_mutex 181*58b9f456SAndroid Build Coastguard Worker{ 182*58b9f456SAndroid Build Coastguard Worker __shared_mutex_base __base; 183*58b9f456SAndroid Build Coastguard Workerpublic: 184*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY shared_mutex() : __base() {} 185*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default; 186*58b9f456SAndroid Build Coastguard Worker 187*58b9f456SAndroid Build Coastguard Worker shared_mutex(const shared_mutex&) = delete; 188*58b9f456SAndroid Build Coastguard Worker shared_mutex& operator=(const shared_mutex&) = delete; 189*58b9f456SAndroid Build Coastguard Worker 190*58b9f456SAndroid Build Coastguard Worker // Exclusive ownership 191*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY void lock() { return __base.lock(); } 192*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); } 193*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY void unlock() { return __base.unlock(); } 194*58b9f456SAndroid Build Coastguard Worker 195*58b9f456SAndroid Build Coastguard Worker // Shared ownership 196*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base.lock_shared(); } 197*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); } 198*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base.unlock_shared(); } 199*58b9f456SAndroid Build Coastguard Worker 200*58b9f456SAndroid Build Coastguard Worker// typedef __shared_mutex_base::native_handle_type native_handle_type; 201*58b9f456SAndroid Build Coastguard Worker// _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); } 202*58b9f456SAndroid Build Coastguard Worker}; 203*58b9f456SAndroid Build Coastguard Worker#endif 204*58b9f456SAndroid Build Coastguard Worker 205*58b9f456SAndroid Build Coastguard Worker 206*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_timed_mutex 207*58b9f456SAndroid Build Coastguard Worker{ 208*58b9f456SAndroid Build Coastguard Worker __shared_mutex_base __base; 209*58b9f456SAndroid Build Coastguard Workerpublic: 210*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex(); 211*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default; 212*58b9f456SAndroid Build Coastguard Worker 213*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex(const shared_timed_mutex&) = delete; 214*58b9f456SAndroid Build Coastguard Worker shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; 215*58b9f456SAndroid Build Coastguard Worker 216*58b9f456SAndroid Build Coastguard Worker // Exclusive ownership 217*58b9f456SAndroid Build Coastguard Worker void lock(); 218*58b9f456SAndroid Build Coastguard Worker bool try_lock(); 219*58b9f456SAndroid Build Coastguard Worker template <class _Rep, class _Period> 220*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 221*58b9f456SAndroid Build Coastguard Worker bool 222*58b9f456SAndroid Build Coastguard Worker try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) 223*58b9f456SAndroid Build Coastguard Worker { 224*58b9f456SAndroid Build Coastguard Worker return try_lock_until(chrono::steady_clock::now() + __rel_time); 225*58b9f456SAndroid Build Coastguard Worker } 226*58b9f456SAndroid Build Coastguard Worker template <class _Clock, class _Duration> 227*58b9f456SAndroid Build Coastguard Worker _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 228*58b9f456SAndroid Build Coastguard Worker bool 229*58b9f456SAndroid Build Coastguard Worker try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time); 230*58b9f456SAndroid Build Coastguard Worker void unlock(); 231*58b9f456SAndroid Build Coastguard Worker 232*58b9f456SAndroid Build Coastguard Worker // Shared ownership 233*58b9f456SAndroid Build Coastguard Worker void lock_shared(); 234*58b9f456SAndroid Build Coastguard Worker bool try_lock_shared(); 235*58b9f456SAndroid Build Coastguard Worker template <class _Rep, class _Period> 236*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 237*58b9f456SAndroid Build Coastguard Worker bool 238*58b9f456SAndroid Build Coastguard Worker try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) 239*58b9f456SAndroid Build Coastguard Worker { 240*58b9f456SAndroid Build Coastguard Worker return try_lock_shared_until(chrono::steady_clock::now() + __rel_time); 241*58b9f456SAndroid Build Coastguard Worker } 242*58b9f456SAndroid Build Coastguard Worker template <class _Clock, class _Duration> 243*58b9f456SAndroid Build Coastguard Worker _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 244*58b9f456SAndroid Build Coastguard Worker bool 245*58b9f456SAndroid Build Coastguard Worker try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time); 246*58b9f456SAndroid Build Coastguard Worker void unlock_shared(); 247*58b9f456SAndroid Build Coastguard Worker}; 248*58b9f456SAndroid Build Coastguard Worker 249*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration> 250*58b9f456SAndroid Build Coastguard Workerbool 251*58b9f456SAndroid Build Coastguard Workershared_timed_mutex::try_lock_until( 252*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __abs_time) 253*58b9f456SAndroid Build Coastguard Worker{ 254*58b9f456SAndroid Build Coastguard Worker unique_lock<mutex> __lk(__base.__mut_); 255*58b9f456SAndroid Build Coastguard Worker if (__base.__state_ & __base.__write_entered_) 256*58b9f456SAndroid Build Coastguard Worker { 257*58b9f456SAndroid Build Coastguard Worker while (true) 258*58b9f456SAndroid Build Coastguard Worker { 259*58b9f456SAndroid Build Coastguard Worker cv_status __status = __base.__gate1_.wait_until(__lk, __abs_time); 260*58b9f456SAndroid Build Coastguard Worker if ((__base.__state_ & __base.__write_entered_) == 0) 261*58b9f456SAndroid Build Coastguard Worker break; 262*58b9f456SAndroid Build Coastguard Worker if (__status == cv_status::timeout) 263*58b9f456SAndroid Build Coastguard Worker return false; 264*58b9f456SAndroid Build Coastguard Worker } 265*58b9f456SAndroid Build Coastguard Worker } 266*58b9f456SAndroid Build Coastguard Worker __base.__state_ |= __base.__write_entered_; 267*58b9f456SAndroid Build Coastguard Worker if (__base.__state_ & __base.__n_readers_) 268*58b9f456SAndroid Build Coastguard Worker { 269*58b9f456SAndroid Build Coastguard Worker while (true) 270*58b9f456SAndroid Build Coastguard Worker { 271*58b9f456SAndroid Build Coastguard Worker cv_status __status = __base.__gate2_.wait_until(__lk, __abs_time); 272*58b9f456SAndroid Build Coastguard Worker if ((__base.__state_ & __base.__n_readers_) == 0) 273*58b9f456SAndroid Build Coastguard Worker break; 274*58b9f456SAndroid Build Coastguard Worker if (__status == cv_status::timeout) 275*58b9f456SAndroid Build Coastguard Worker { 276*58b9f456SAndroid Build Coastguard Worker __base.__state_ &= ~__base.__write_entered_; 277*58b9f456SAndroid Build Coastguard Worker __base.__gate1_.notify_all(); 278*58b9f456SAndroid Build Coastguard Worker return false; 279*58b9f456SAndroid Build Coastguard Worker } 280*58b9f456SAndroid Build Coastguard Worker } 281*58b9f456SAndroid Build Coastguard Worker } 282*58b9f456SAndroid Build Coastguard Worker return true; 283*58b9f456SAndroid Build Coastguard Worker} 284*58b9f456SAndroid Build Coastguard Worker 285*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration> 286*58b9f456SAndroid Build Coastguard Workerbool 287*58b9f456SAndroid Build Coastguard Workershared_timed_mutex::try_lock_shared_until( 288*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __abs_time) 289*58b9f456SAndroid Build Coastguard Worker{ 290*58b9f456SAndroid Build Coastguard Worker unique_lock<mutex> __lk(__base.__mut_); 291*58b9f456SAndroid Build Coastguard Worker if ((__base.__state_ & __base.__write_entered_) || (__base.__state_ & __base.__n_readers_) == __base.__n_readers_) 292*58b9f456SAndroid Build Coastguard Worker { 293*58b9f456SAndroid Build Coastguard Worker while (true) 294*58b9f456SAndroid Build Coastguard Worker { 295*58b9f456SAndroid Build Coastguard Worker cv_status status = __base.__gate1_.wait_until(__lk, __abs_time); 296*58b9f456SAndroid Build Coastguard Worker if ((__base.__state_ & __base.__write_entered_) == 0 && 297*58b9f456SAndroid Build Coastguard Worker (__base.__state_ & __base.__n_readers_) < __base.__n_readers_) 298*58b9f456SAndroid Build Coastguard Worker break; 299*58b9f456SAndroid Build Coastguard Worker if (status == cv_status::timeout) 300*58b9f456SAndroid Build Coastguard Worker return false; 301*58b9f456SAndroid Build Coastguard Worker } 302*58b9f456SAndroid Build Coastguard Worker } 303*58b9f456SAndroid Build Coastguard Worker unsigned __num_readers = (__base.__state_ & __base.__n_readers_) + 1; 304*58b9f456SAndroid Build Coastguard Worker __base.__state_ &= ~__base.__n_readers_; 305*58b9f456SAndroid Build Coastguard Worker __base.__state_ |= __num_readers; 306*58b9f456SAndroid Build Coastguard Worker return true; 307*58b9f456SAndroid Build Coastguard Worker} 308*58b9f456SAndroid Build Coastguard Worker 309*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 310*58b9f456SAndroid Build Coastguard Workerclass shared_lock 311*58b9f456SAndroid Build Coastguard Worker{ 312*58b9f456SAndroid Build Coastguard Workerpublic: 313*58b9f456SAndroid Build Coastguard Worker typedef _Mutex mutex_type; 314*58b9f456SAndroid Build Coastguard Worker 315*58b9f456SAndroid Build Coastguard Workerprivate: 316*58b9f456SAndroid Build Coastguard Worker mutex_type* __m_; 317*58b9f456SAndroid Build Coastguard Worker bool __owns_; 318*58b9f456SAndroid Build Coastguard Worker 319*58b9f456SAndroid Build Coastguard Workerpublic: 320*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 321*58b9f456SAndroid Build Coastguard Worker shared_lock() _NOEXCEPT 322*58b9f456SAndroid Build Coastguard Worker : __m_(nullptr), 323*58b9f456SAndroid Build Coastguard Worker __owns_(false) 324*58b9f456SAndroid Build Coastguard Worker {} 325*58b9f456SAndroid Build Coastguard Worker 326*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 327*58b9f456SAndroid Build Coastguard Worker explicit shared_lock(mutex_type& __m) 328*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 329*58b9f456SAndroid Build Coastguard Worker __owns_(true) 330*58b9f456SAndroid Build Coastguard Worker {__m_->lock_shared();} 331*58b9f456SAndroid Build Coastguard Worker 332*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 333*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT 334*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 335*58b9f456SAndroid Build Coastguard Worker __owns_(false) 336*58b9f456SAndroid Build Coastguard Worker {} 337*58b9f456SAndroid Build Coastguard Worker 338*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 339*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& __m, try_to_lock_t) 340*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 341*58b9f456SAndroid Build Coastguard Worker __owns_(__m.try_lock_shared()) 342*58b9f456SAndroid Build Coastguard Worker {} 343*58b9f456SAndroid Build Coastguard Worker 344*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 345*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& __m, adopt_lock_t) 346*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 347*58b9f456SAndroid Build Coastguard Worker __owns_(true) 348*58b9f456SAndroid Build Coastguard Worker {} 349*58b9f456SAndroid Build Coastguard Worker 350*58b9f456SAndroid Build Coastguard Worker template <class _Clock, class _Duration> 351*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 352*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& __m, 353*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __abs_time) 354*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 355*58b9f456SAndroid Build Coastguard Worker __owns_(__m.try_lock_shared_until(__abs_time)) 356*58b9f456SAndroid Build Coastguard Worker {} 357*58b9f456SAndroid Build Coastguard Worker 358*58b9f456SAndroid Build Coastguard Worker template <class _Rep, class _Period> 359*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 360*58b9f456SAndroid Build Coastguard Worker shared_lock(mutex_type& __m, 361*58b9f456SAndroid Build Coastguard Worker const chrono::duration<_Rep, _Period>& __rel_time) 362*58b9f456SAndroid Build Coastguard Worker : __m_(_VSTD::addressof(__m)), 363*58b9f456SAndroid Build Coastguard Worker __owns_(__m.try_lock_shared_for(__rel_time)) 364*58b9f456SAndroid Build Coastguard Worker {} 365*58b9f456SAndroid Build Coastguard Worker 366*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 367*58b9f456SAndroid Build Coastguard Worker ~shared_lock() 368*58b9f456SAndroid Build Coastguard Worker { 369*58b9f456SAndroid Build Coastguard Worker if (__owns_) 370*58b9f456SAndroid Build Coastguard Worker __m_->unlock_shared(); 371*58b9f456SAndroid Build Coastguard Worker } 372*58b9f456SAndroid Build Coastguard Worker 373*58b9f456SAndroid Build Coastguard Worker shared_lock(shared_lock const&) = delete; 374*58b9f456SAndroid Build Coastguard Worker shared_lock& operator=(shared_lock const&) = delete; 375*58b9f456SAndroid Build Coastguard Worker 376*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 377*58b9f456SAndroid Build Coastguard Worker shared_lock(shared_lock&& __u) _NOEXCEPT 378*58b9f456SAndroid Build Coastguard Worker : __m_(__u.__m_), 379*58b9f456SAndroid Build Coastguard Worker __owns_(__u.__owns_) 380*58b9f456SAndroid Build Coastguard Worker { 381*58b9f456SAndroid Build Coastguard Worker __u.__m_ = nullptr; 382*58b9f456SAndroid Build Coastguard Worker __u.__owns_ = false; 383*58b9f456SAndroid Build Coastguard Worker } 384*58b9f456SAndroid Build Coastguard Worker 385*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 386*58b9f456SAndroid Build Coastguard Worker shared_lock& operator=(shared_lock&& __u) _NOEXCEPT 387*58b9f456SAndroid Build Coastguard Worker { 388*58b9f456SAndroid Build Coastguard Worker if (__owns_) 389*58b9f456SAndroid Build Coastguard Worker __m_->unlock_shared(); 390*58b9f456SAndroid Build Coastguard Worker __m_ = nullptr; 391*58b9f456SAndroid Build Coastguard Worker __owns_ = false; 392*58b9f456SAndroid Build Coastguard Worker __m_ = __u.__m_; 393*58b9f456SAndroid Build Coastguard Worker __owns_ = __u.__owns_; 394*58b9f456SAndroid Build Coastguard Worker __u.__m_ = nullptr; 395*58b9f456SAndroid Build Coastguard Worker __u.__owns_ = false; 396*58b9f456SAndroid Build Coastguard Worker return *this; 397*58b9f456SAndroid Build Coastguard Worker } 398*58b9f456SAndroid Build Coastguard Worker 399*58b9f456SAndroid Build Coastguard Worker void lock(); 400*58b9f456SAndroid Build Coastguard Worker bool try_lock(); 401*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 402*58b9f456SAndroid Build Coastguard Worker bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 403*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 404*58b9f456SAndroid Build Coastguard Worker bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 405*58b9f456SAndroid Build Coastguard Worker void unlock(); 406*58b9f456SAndroid Build Coastguard Worker 407*58b9f456SAndroid Build Coastguard Worker // Setters 408*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 409*58b9f456SAndroid Build Coastguard Worker void swap(shared_lock& __u) _NOEXCEPT 410*58b9f456SAndroid Build Coastguard Worker { 411*58b9f456SAndroid Build Coastguard Worker _VSTD::swap(__m_, __u.__m_); 412*58b9f456SAndroid Build Coastguard Worker _VSTD::swap(__owns_, __u.__owns_); 413*58b9f456SAndroid Build Coastguard Worker } 414*58b9f456SAndroid Build Coastguard Worker 415*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 416*58b9f456SAndroid Build Coastguard Worker mutex_type* release() _NOEXCEPT 417*58b9f456SAndroid Build Coastguard Worker { 418*58b9f456SAndroid Build Coastguard Worker mutex_type* __m = __m_; 419*58b9f456SAndroid Build Coastguard Worker __m_ = nullptr; 420*58b9f456SAndroid Build Coastguard Worker __owns_ = false; 421*58b9f456SAndroid Build Coastguard Worker return __m; 422*58b9f456SAndroid Build Coastguard Worker } 423*58b9f456SAndroid Build Coastguard Worker 424*58b9f456SAndroid Build Coastguard Worker // Getters 425*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 426*58b9f456SAndroid Build Coastguard Worker bool owns_lock() const _NOEXCEPT {return __owns_;} 427*58b9f456SAndroid Build Coastguard Worker 428*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 429*58b9f456SAndroid Build Coastguard Worker explicit operator bool () const _NOEXCEPT {return __owns_;} 430*58b9f456SAndroid Build Coastguard Worker 431*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 432*58b9f456SAndroid Build Coastguard Worker mutex_type* mutex() const _NOEXCEPT {return __m_;} 433*58b9f456SAndroid Build Coastguard Worker}; 434*58b9f456SAndroid Build Coastguard Worker 435*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 436*58b9f456SAndroid Build Coastguard Workervoid 437*58b9f456SAndroid Build Coastguard Workershared_lock<_Mutex>::lock() 438*58b9f456SAndroid Build Coastguard Worker{ 439*58b9f456SAndroid Build Coastguard Worker if (__m_ == nullptr) 440*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EPERM, "shared_lock::lock: references null mutex"); 441*58b9f456SAndroid Build Coastguard Worker if (__owns_) 442*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EDEADLK, "shared_lock::lock: already locked"); 443*58b9f456SAndroid Build Coastguard Worker __m_->lock_shared(); 444*58b9f456SAndroid Build Coastguard Worker __owns_ = true; 445*58b9f456SAndroid Build Coastguard Worker} 446*58b9f456SAndroid Build Coastguard Worker 447*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 448*58b9f456SAndroid Build Coastguard Workerbool 449*58b9f456SAndroid Build Coastguard Workershared_lock<_Mutex>::try_lock() 450*58b9f456SAndroid Build Coastguard Worker{ 451*58b9f456SAndroid Build Coastguard Worker if (__m_ == nullptr) 452*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex"); 453*58b9f456SAndroid Build Coastguard Worker if (__owns_) 454*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked"); 455*58b9f456SAndroid Build Coastguard Worker __owns_ = __m_->try_lock_shared(); 456*58b9f456SAndroid Build Coastguard Worker return __owns_; 457*58b9f456SAndroid Build Coastguard Worker} 458*58b9f456SAndroid Build Coastguard Worker 459*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 460*58b9f456SAndroid Build Coastguard Workertemplate <class _Rep, class _Period> 461*58b9f456SAndroid Build Coastguard Workerbool 462*58b9f456SAndroid Build Coastguard Workershared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) 463*58b9f456SAndroid Build Coastguard Worker{ 464*58b9f456SAndroid Build Coastguard Worker if (__m_ == nullptr) 465*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex"); 466*58b9f456SAndroid Build Coastguard Worker if (__owns_) 467*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked"); 468*58b9f456SAndroid Build Coastguard Worker __owns_ = __m_->try_lock_shared_for(__d); 469*58b9f456SAndroid Build Coastguard Worker return __owns_; 470*58b9f456SAndroid Build Coastguard Worker} 471*58b9f456SAndroid Build Coastguard Worker 472*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 473*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration> 474*58b9f456SAndroid Build Coastguard Workerbool 475*58b9f456SAndroid Build Coastguard Workershared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 476*58b9f456SAndroid Build Coastguard Worker{ 477*58b9f456SAndroid Build Coastguard Worker if (__m_ == nullptr) 478*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex"); 479*58b9f456SAndroid Build Coastguard Worker if (__owns_) 480*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked"); 481*58b9f456SAndroid Build Coastguard Worker __owns_ = __m_->try_lock_shared_until(__t); 482*58b9f456SAndroid Build Coastguard Worker return __owns_; 483*58b9f456SAndroid Build Coastguard Worker} 484*58b9f456SAndroid Build Coastguard Worker 485*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 486*58b9f456SAndroid Build Coastguard Workervoid 487*58b9f456SAndroid Build Coastguard Workershared_lock<_Mutex>::unlock() 488*58b9f456SAndroid Build Coastguard Worker{ 489*58b9f456SAndroid Build Coastguard Worker if (!__owns_) 490*58b9f456SAndroid Build Coastguard Worker __throw_system_error(EPERM, "shared_lock::unlock: not locked"); 491*58b9f456SAndroid Build Coastguard Worker __m_->unlock_shared(); 492*58b9f456SAndroid Build Coastguard Worker __owns_ = false; 493*58b9f456SAndroid Build Coastguard Worker} 494*58b9f456SAndroid Build Coastguard Worker 495*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex> 496*58b9f456SAndroid Build Coastguard Workerinline _LIBCPP_INLINE_VISIBILITY 497*58b9f456SAndroid Build Coastguard Workervoid 498*58b9f456SAndroid Build Coastguard Workerswap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT 499*58b9f456SAndroid Build Coastguard Worker {__x.swap(__y);} 500*58b9f456SAndroid Build Coastguard Worker 501*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_STD 502*58b9f456SAndroid Build Coastguard Worker 503*58b9f456SAndroid Build Coastguard Worker#endif // !_LIBCPP_HAS_NO_THREADS 504*58b9f456SAndroid Build Coastguard Worker 505*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_STD_VER > 11 506*58b9f456SAndroid Build Coastguard Worker 507*58b9f456SAndroid Build Coastguard Worker_LIBCPP_POP_MACROS 508*58b9f456SAndroid Build Coastguard Worker 509*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_SHARED_MUTEX 510