Warning, /include/c++/v1/__cxx03/mutex is written in an unsupported language. File is not indexed.
0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009
0010 #ifndef _LIBCPP___CXX03_MUTEX
0011 #define _LIBCPP___CXX03_MUTEX
0012
0013 /*
0014 mutex synopsis
0015
0016 namespace std
0017 {
0018
0019 class mutex
0020 {
0021 public:
0022 constexpr mutex() noexcept;
0023 ~mutex();
0024
0025 mutex(const mutex&) = delete;
0026 mutex& operator=(const mutex&) = delete;
0027
0028 void lock();
0029 bool try_lock();
0030 void unlock();
0031
0032 typedef pthread_mutex_t* native_handle_type;
0033 native_handle_type native_handle();
0034 };
0035
0036 class recursive_mutex
0037 {
0038 public:
0039 recursive_mutex();
0040 ~recursive_mutex();
0041
0042 recursive_mutex(const recursive_mutex&) = delete;
0043 recursive_mutex& operator=(const recursive_mutex&) = delete;
0044
0045 void lock();
0046 bool try_lock() noexcept;
0047 void unlock();
0048
0049 typedef pthread_mutex_t* native_handle_type;
0050 native_handle_type native_handle();
0051 };
0052
0053 class timed_mutex
0054 {
0055 public:
0056 timed_mutex();
0057 ~timed_mutex();
0058
0059 timed_mutex(const timed_mutex&) = delete;
0060 timed_mutex& operator=(const timed_mutex&) = delete;
0061
0062 void lock();
0063 bool try_lock();
0064 template <class Rep, class Period>
0065 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0066 template <class Clock, class Duration>
0067 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0068 void unlock();
0069 };
0070
0071 class recursive_timed_mutex
0072 {
0073 public:
0074 recursive_timed_mutex();
0075 ~recursive_timed_mutex();
0076
0077 recursive_timed_mutex(const recursive_timed_mutex&) = delete;
0078 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
0079
0080 void lock();
0081 bool try_lock() noexcept;
0082 template <class Rep, class Period>
0083 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0084 template <class Clock, class Duration>
0085 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0086 void unlock();
0087 };
0088
0089 struct defer_lock_t { explicit defer_lock_t() = default; };
0090 struct try_to_lock_t { explicit try_to_lock_t() = default; };
0091 struct adopt_lock_t { explicit adopt_lock_t() = default; };
0092
0093 inline constexpr defer_lock_t defer_lock{};
0094 inline constexpr try_to_lock_t try_to_lock{};
0095 inline constexpr adopt_lock_t adopt_lock{};
0096
0097 template <class Mutex>
0098 class lock_guard
0099 {
0100 public:
0101 typedef Mutex mutex_type;
0102
0103 explicit lock_guard(mutex_type& m);
0104 lock_guard(mutex_type& m, adopt_lock_t);
0105 ~lock_guard();
0106
0107 lock_guard(lock_guard const&) = delete;
0108 lock_guard& operator=(lock_guard const&) = delete;
0109 };
0110
0111 template <class... MutexTypes>
0112 class scoped_lock // C++17
0113 {
0114 public:
0115 using mutex_type = Mutex; // Only if sizeof...(MutexTypes) == 1
0116
0117 explicit scoped_lock(MutexTypes&... m);
0118 scoped_lock(adopt_lock_t, MutexTypes&... m);
0119 ~scoped_lock();
0120 scoped_lock(scoped_lock const&) = delete;
0121 scoped_lock& operator=(scoped_lock const&) = delete;
0122 private:
0123 tuple<MutexTypes&...> pm; // exposition only
0124 };
0125
0126 template <class Mutex>
0127 class unique_lock
0128 {
0129 public:
0130 typedef Mutex mutex_type;
0131 unique_lock() noexcept;
0132 explicit unique_lock(mutex_type& m);
0133 unique_lock(mutex_type& m, defer_lock_t) noexcept;
0134 unique_lock(mutex_type& m, try_to_lock_t);
0135 unique_lock(mutex_type& m, adopt_lock_t);
0136 template <class Clock, class Duration>
0137 unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
0138 template <class Rep, class Period>
0139 unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
0140 ~unique_lock();
0141
0142 unique_lock(unique_lock const&) = delete;
0143 unique_lock& operator=(unique_lock const&) = delete;
0144
0145 unique_lock(unique_lock&& u) noexcept;
0146 unique_lock& operator=(unique_lock&& u) noexcept;
0147
0148 void lock();
0149 bool try_lock();
0150
0151 template <class Rep, class Period>
0152 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0153 template <class Clock, class Duration>
0154 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0155
0156 void unlock();
0157
0158 void swap(unique_lock& u) noexcept;
0159 mutex_type* release() noexcept;
0160
0161 bool owns_lock() const noexcept;
0162 explicit operator bool () const noexcept;
0163 mutex_type* mutex() const noexcept;
0164 };
0165
0166 template <class Mutex>
0167 void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
0168
0169 template <class L1, class L2, class... L3>
0170 int try_lock(L1&, L2&, L3&...);
0171 template <class L1, class L2, class... L3>
0172 void lock(L1&, L2&, L3&...);
0173
0174 struct once_flag
0175 {
0176 constexpr once_flag() noexcept;
0177
0178 once_flag(const once_flag&) = delete;
0179 once_flag& operator=(const once_flag&) = delete;
0180 };
0181
0182 template<class Callable, class ...Args>
0183 void call_once(once_flag& flag, Callable&& func, Args&&... args);
0184
0185 } // std
0186
0187 */
0188
0189 #include <__cxx03/__chrono/steady_clock.h>
0190 #include <__cxx03/__chrono/time_point.h>
0191 #include <__cxx03/__condition_variable/condition_variable.h>
0192 #include <__cxx03/__config>
0193 #include <__cxx03/__memory/shared_ptr.h>
0194 #include <__cxx03/__mutex/lock_guard.h>
0195 #include <__cxx03/__mutex/mutex.h>
0196 #include <__cxx03/__mutex/once_flag.h>
0197 #include <__cxx03/__mutex/tag_types.h>
0198 #include <__cxx03/__mutex/unique_lock.h>
0199 #include <__cxx03/__thread/id.h>
0200 #include <__cxx03/__thread/support.h>
0201 #include <__cxx03/__utility/forward.h>
0202 #include <__cxx03/cstddef>
0203 #include <__cxx03/limits>
0204 #ifndef _LIBCPP_CXX03_LANG
0205 # include <__cxx03/tuple>
0206 #endif
0207 #include <__cxx03/version>
0208
0209 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0210 # pragma GCC system_header
0211 #endif
0212
0213 _LIBCPP_PUSH_MACROS
0214 #include <__cxx03/__undef_macros>
0215
0216 _LIBCPP_BEGIN_NAMESPACE_STD
0217
0218 #ifndef _LIBCPP_HAS_NO_THREADS
0219
0220 class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex {
0221 __libcpp_recursive_mutex_t __m_;
0222
0223 public:
0224 recursive_mutex();
0225 ~recursive_mutex();
0226
0227 recursive_mutex(const recursive_mutex&) = delete;
0228 recursive_mutex& operator=(const recursive_mutex&) = delete;
0229
0230 void lock();
0231 bool try_lock() _NOEXCEPT;
0232 void unlock() _NOEXCEPT;
0233
0234 typedef __libcpp_recursive_mutex_t* native_handle_type;
0235
0236 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
0237 };
0238
0239 class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
0240 mutex __m_;
0241 condition_variable __cv_;
0242 bool __locked_;
0243
0244 public:
0245 timed_mutex();
0246 ~timed_mutex();
0247
0248 timed_mutex(const timed_mutex&) = delete;
0249 timed_mutex& operator=(const timed_mutex&) = delete;
0250
0251 public:
0252 void lock();
0253 bool try_lock() _NOEXCEPT;
0254 template <class _Rep, class _Period>
0255 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
0256 return try_lock_until(chrono::steady_clock::now() + __d);
0257 }
0258 template <class _Clock, class _Duration>
0259 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
0260 try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
0261 void unlock() _NOEXCEPT;
0262 };
0263
0264 template <class _Clock, class _Duration>
0265 bool timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
0266 using namespace chrono;
0267 unique_lock<mutex> __lk(__m_);
0268 bool __no_timeout = _Clock::now() < __t;
0269 while (__no_timeout && __locked_)
0270 __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
0271 if (!__locked_) {
0272 __locked_ = true;
0273 return true;
0274 }
0275 return false;
0276 }
0277
0278 class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex {
0279 mutex __m_;
0280 condition_variable __cv_;
0281 size_t __count_;
0282 __thread_id __id_;
0283
0284 public:
0285 recursive_timed_mutex();
0286 ~recursive_timed_mutex();
0287
0288 recursive_timed_mutex(const recursive_timed_mutex&) = delete;
0289 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
0290
0291 void lock();
0292 bool try_lock() _NOEXCEPT;
0293 template <class _Rep, class _Period>
0294 _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
0295 return try_lock_until(chrono::steady_clock::now() + __d);
0296 }
0297 template <class _Clock, class _Duration>
0298 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
0299 try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
0300 void unlock() _NOEXCEPT;
0301 };
0302
0303 template <class _Clock, class _Duration>
0304 bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
0305 using namespace chrono;
0306 __thread_id __id = this_thread::get_id();
0307 unique_lock<mutex> __lk(__m_);
0308 if (__id == __id_) {
0309 if (__count_ == numeric_limits<size_t>::max())
0310 return false;
0311 ++__count_;
0312 return true;
0313 }
0314 bool __no_timeout = _Clock::now() < __t;
0315 while (__no_timeout && __count_ != 0)
0316 __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
0317 if (__count_ == 0) {
0318 __count_ = 1;
0319 __id_ = __id;
0320 return true;
0321 }
0322 return false;
0323 }
0324
0325 template <class _L0, class _L1>
0326 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
0327 unique_lock<_L0> __u0(__l0, try_to_lock_t());
0328 if (__u0.owns_lock()) {
0329 if (__l1.try_lock()) {
0330 __u0.release();
0331 return -1;
0332 } else
0333 return 1;
0334 }
0335 return 0;
0336 }
0337
0338 # ifndef _LIBCPP_CXX03_LANG
0339
0340 template <class _L0, class _L1, class _L2, class... _L3>
0341 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0342 int __r = 0;
0343 unique_lock<_L0> __u0(__l0, try_to_lock);
0344 if (__u0.owns_lock()) {
0345 __r = std::try_lock(__l1, __l2, __l3...);
0346 if (__r == -1)
0347 __u0.release();
0348 else
0349 ++__r;
0350 }
0351 return __r;
0352 }
0353
0354 # endif // _LIBCPP_CXX03_LANG
0355
0356 template <class _L0, class _L1>
0357 _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
0358 while (true) {
0359 {
0360 unique_lock<_L0> __u0(__l0);
0361 if (__l1.try_lock()) {
0362 __u0.release();
0363 break;
0364 }
0365 }
0366 __libcpp_thread_yield();
0367 {
0368 unique_lock<_L1> __u1(__l1);
0369 if (__l0.try_lock()) {
0370 __u1.release();
0371 break;
0372 }
0373 }
0374 __libcpp_thread_yield();
0375 }
0376 }
0377
0378 # ifndef _LIBCPP_CXX03_LANG
0379
0380 template <class _L0, class _L1, class _L2, class... _L3>
0381 void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0382 while (true) {
0383 switch (__i) {
0384 case 0: {
0385 unique_lock<_L0> __u0(__l0);
0386 __i = std::try_lock(__l1, __l2, __l3...);
0387 if (__i == -1) {
0388 __u0.release();
0389 return;
0390 }
0391 }
0392 ++__i;
0393 __libcpp_thread_yield();
0394 break;
0395 case 1: {
0396 unique_lock<_L1> __u1(__l1);
0397 __i = std::try_lock(__l2, __l3..., __l0);
0398 if (__i == -1) {
0399 __u1.release();
0400 return;
0401 }
0402 }
0403 if (__i == sizeof...(_L3) + 1)
0404 __i = 0;
0405 else
0406 __i += 2;
0407 __libcpp_thread_yield();
0408 break;
0409 default:
0410 std::__lock_first(__i - 2, __l2, __l3..., __l0, __l1);
0411 return;
0412 }
0413 }
0414 }
0415
0416 template <class _L0, class _L1, class _L2, class... _L3>
0417 inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0418 std::__lock_first(0, __l0, __l1, __l2, __l3...);
0419 }
0420
0421 # endif // _LIBCPP_CXX03_LANG
0422
0423 # if _LIBCPP_STD_VER >= 17
0424 template <class... _Mutexes>
0425 class _LIBCPP_TEMPLATE_VIS scoped_lock;
0426
0427 template <>
0428 class _LIBCPP_TEMPLATE_VIS scoped_lock<> {
0429 public:
0430 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock() {}
0431 ~scoped_lock() = default;
0432
0433 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t) {}
0434
0435 scoped_lock(scoped_lock const&) = delete;
0436 scoped_lock& operator=(scoped_lock const&) = delete;
0437 };
0438
0439 template <class _Mutex>
0440 class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
0441 public:
0442 typedef _Mutex mutex_type;
0443
0444 private:
0445 mutex_type& __m_;
0446
0447 public:
0448 [[nodiscard]]
0449 _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
0450 : __m_(__m) {
0451 __m_.lock();
0452 }
0453
0454 ~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
0455
0456 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m)
0457 _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
0458 : __m_(__m) {}
0459
0460 scoped_lock(scoped_lock const&) = delete;
0461 scoped_lock& operator=(scoped_lock const&) = delete;
0462 };
0463
0464 template <class... _MArgs>
0465 class _LIBCPP_TEMPLATE_VIS scoped_lock {
0466 static_assert(sizeof...(_MArgs) > 1, "At least 2 lock types required");
0467 typedef tuple<_MArgs&...> _MutexTuple;
0468
0469 public:
0470 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(_MArgs&... __margs) : __t_(__margs...) {
0471 std::lock(__margs...);
0472 }
0473
0474 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI scoped_lock(adopt_lock_t, _MArgs&... __margs) : __t_(__margs...) {}
0475
0476 _LIBCPP_HIDE_FROM_ABI ~scoped_lock() {
0477 typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices;
0478 __unlock_unpack(_Indices{}, __t_);
0479 }
0480
0481 scoped_lock(scoped_lock const&) = delete;
0482 scoped_lock& operator=(scoped_lock const&) = delete;
0483
0484 private:
0485 template <size_t... _Indx>
0486 _LIBCPP_HIDE_FROM_ABI static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) {
0487 (std::get<_Indx>(__mt).unlock(), ...);
0488 }
0489
0490 _MutexTuple __t_;
0491 };
0492 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
0493
0494 # endif // _LIBCPP_STD_VER >= 17
0495 #endif // !_LIBCPP_HAS_NO_THREADS
0496
0497 _LIBCPP_END_NAMESPACE_STD
0498
0499 _LIBCPP_POP_MACROS
0500
0501 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
0502 # include <__cxx03/atomic>
0503 # include <__cxx03/concepts>
0504 # include <__cxx03/cstdlib>
0505 # include <__cxx03/cstring>
0506 # include <__cxx03/ctime>
0507 # include <__cxx03/initializer_list>
0508 # include <__cxx03/iosfwd>
0509 # include <__cxx03/new>
0510 # include <__cxx03/stdexcept>
0511 # include <__cxx03/system_error>
0512 # include <__cxx03/type_traits>
0513 # include <__cxx03/typeinfo>
0514 #endif
0515
0516 #endif // _LIBCPP___CXX03_MUTEX