Home | History | Annotate | Line # | Download | only in std
      1   1.1  mrg // <mutex> -*- C++ -*-
      2   1.1  mrg 
      3  1.12  mrg // Copyright (C) 2003-2022 Free Software Foundation, Inc.
      4   1.1  mrg //
      5   1.1  mrg // This file is part of the GNU ISO C++ Library.  This library is free
      6   1.1  mrg // software; you can redistribute it and/or modify it under the
      7   1.1  mrg // terms of the GNU General Public License as published by the
      8   1.1  mrg // Free Software Foundation; either version 3, or (at your option)
      9   1.1  mrg // any later version.
     10   1.1  mrg 
     11   1.1  mrg // This library is distributed in the hope that it will be useful,
     12   1.1  mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  mrg // GNU General Public License for more details.
     15   1.1  mrg 
     16   1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     17   1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     18   1.1  mrg // 3.1, as published by the Free Software Foundation.
     19   1.1  mrg 
     20   1.1  mrg // You should have received a copy of the GNU General Public License and
     21   1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     22   1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23   1.1  mrg // <http://www.gnu.org/licenses/>.
     24   1.1  mrg 
     25   1.3  mrg /** @file include/mutex
     26   1.1  mrg  *  This is a Standard C++ Library header.
     27   1.1  mrg  */
     28   1.1  mrg 
     29   1.1  mrg #ifndef _GLIBCXX_MUTEX
     30   1.1  mrg #define _GLIBCXX_MUTEX 1
     31   1.1  mrg 
     32   1.1  mrg #pragma GCC system_header
     33   1.1  mrg 
     34   1.3  mrg #if __cplusplus < 201103L
     35   1.1  mrg # include <bits/c++0x_warning.h>
     36   1.1  mrg #else
     37   1.1  mrg 
     38   1.1  mrg #include <tuple>
     39   1.1  mrg #include <exception>
     40   1.1  mrg #include <type_traits>
     41   1.1  mrg #include <system_error>
     42  1.12  mrg #include <bits/chrono.h>
     43   1.6  mrg #include <bits/std_mutex.h>
     44  1.10  mrg #include <bits/unique_lock.h>
     45   1.6  mrg #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK
     46   1.6  mrg # include <condition_variable>
     47   1.6  mrg # include <thread>
     48   1.6  mrg #endif
     49  1.12  mrg #include <ext/atomicity.h>     // __gnu_cxx::__is_single_threaded
     50  1.12  mrg 
     51  1.12  mrg #if defined _GLIBCXX_HAS_GTHREADS && ! defined _GLIBCXX_HAVE_TLS
     52  1.12  mrg # include <bits/std_function.h>  // std::function
     53   1.8  mrg #endif
     54   1.1  mrg 
     55   1.3  mrg namespace std _GLIBCXX_VISIBILITY(default)
     56   1.1  mrg {
     57   1.3  mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
     58   1.3  mrg 
     59   1.6  mrg   /**
     60  1.11  mrg    * @addtogroup mutexes
     61   1.6  mrg    * @{
     62   1.6  mrg    */
     63   1.6  mrg 
     64   1.3  mrg #ifdef _GLIBCXX_HAS_GTHREADS
     65  1.12  mrg   /// @cond undocumented
     66   1.3  mrg 
     67   1.5  mrg   // Common base class for std::recursive_mutex and std::recursive_timed_mutex
     68   1.3  mrg   class __recursive_mutex_base
     69   1.3  mrg   {
     70   1.3  mrg   protected:
     71   1.3  mrg     typedef __gthread_recursive_mutex_t		__native_type;
     72   1.3  mrg 
     73   1.3  mrg     __recursive_mutex_base(const __recursive_mutex_base&) = delete;
     74   1.3  mrg     __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete;
     75   1.3  mrg 
     76   1.3  mrg #ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
     77   1.3  mrg     __native_type  _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
     78   1.3  mrg 
     79   1.3  mrg     __recursive_mutex_base() = default;
     80   1.3  mrg #else
     81   1.3  mrg     __native_type  _M_mutex;
     82   1.3  mrg 
     83   1.3  mrg     __recursive_mutex_base()
     84   1.3  mrg     {
     85   1.3  mrg       // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
     86   1.3  mrg       __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
     87   1.3  mrg     }
     88   1.3  mrg 
     89   1.3  mrg     ~__recursive_mutex_base()
     90   1.3  mrg     { __gthread_recursive_mutex_destroy(&_M_mutex); }
     91   1.3  mrg #endif
     92   1.3  mrg   };
     93  1.12  mrg   /// @endcond
     94   1.3  mrg 
     95  1.12  mrg   /** The standard recursive mutex type.
     96  1.12  mrg    *
     97  1.12  mrg    * A recursive mutex can be locked more than once by the same thread.
     98  1.12  mrg    * Other threads cannot lock the mutex until the owning thread unlocks it
     99  1.12  mrg    * as many times as it was locked.
    100  1.12  mrg    *
    101  1.12  mrg    * @headerfile mutex
    102  1.12  mrg    * @since C++11
    103  1.12  mrg    */
    104   1.3  mrg   class recursive_mutex : private __recursive_mutex_base
    105   1.1  mrg   {
    106   1.1  mrg   public:
    107   1.1  mrg     typedef __native_type* 			native_handle_type;
    108   1.1  mrg 
    109   1.3  mrg     recursive_mutex() = default;
    110   1.3  mrg     ~recursive_mutex() = default;
    111   1.1  mrg 
    112   1.1  mrg     recursive_mutex(const recursive_mutex&) = delete;
    113   1.1  mrg     recursive_mutex& operator=(const recursive_mutex&) = delete;
    114   1.1  mrg 
    115   1.1  mrg     void
    116   1.1  mrg     lock()
    117   1.1  mrg     {
    118   1.1  mrg       int __e = __gthread_recursive_mutex_lock(&_M_mutex);
    119   1.1  mrg 
    120   1.1  mrg       // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
    121   1.1  mrg       if (__e)
    122   1.1  mrg 	__throw_system_error(__e);
    123   1.1  mrg     }
    124   1.1  mrg 
    125   1.1  mrg     bool
    126   1.3  mrg     try_lock() noexcept
    127   1.1  mrg     {
    128   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    129   1.1  mrg       return !__gthread_recursive_mutex_trylock(&_M_mutex);
    130   1.1  mrg     }
    131   1.1  mrg 
    132   1.1  mrg     void
    133   1.1  mrg     unlock()
    134   1.1  mrg     {
    135   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    136   1.1  mrg       __gthread_recursive_mutex_unlock(&_M_mutex);
    137   1.1  mrg     }
    138   1.1  mrg 
    139   1.1  mrg     native_handle_type
    140   1.8  mrg     native_handle() noexcept
    141   1.1  mrg     { return &_M_mutex; }
    142   1.1  mrg   };
    143   1.1  mrg 
    144   1.3  mrg #if _GTHREAD_USE_MUTEX_TIMEDLOCK
    145  1.12  mrg   /// @cond undocumented
    146  1.12  mrg 
    147   1.5  mrg   template<typename _Derived>
    148   1.5  mrg     class __timed_mutex_impl
    149   1.5  mrg     {
    150   1.5  mrg     protected:
    151   1.5  mrg       template<typename _Rep, typename _Period>
    152   1.5  mrg 	bool
    153   1.5  mrg 	_M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
    154   1.5  mrg 	{
    155  1.11  mrg #if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
    156  1.11  mrg 	  using __clock = chrono::steady_clock;
    157  1.11  mrg #else
    158  1.11  mrg 	  using __clock = chrono::system_clock;
    159  1.11  mrg #endif
    160  1.11  mrg 
    161  1.11  mrg 	  auto __rt = chrono::duration_cast<__clock::duration>(__rtime);
    162  1.11  mrg 	  if (ratio_greater<__clock::period, _Period>())
    163   1.5  mrg 	    ++__rt;
    164  1.11  mrg 	  return _M_try_lock_until(__clock::now() + __rt);
    165   1.5  mrg 	}
    166   1.5  mrg 
    167   1.5  mrg       template<typename _Duration>
    168   1.5  mrg 	bool
    169  1.11  mrg 	_M_try_lock_until(const chrono::time_point<chrono::system_clock,
    170   1.5  mrg 						   _Duration>& __atime)
    171   1.5  mrg 	{
    172   1.5  mrg 	  auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
    173   1.5  mrg 	  auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
    174   1.5  mrg 
    175   1.5  mrg 	  __gthread_time_t __ts = {
    176   1.5  mrg 	    static_cast<std::time_t>(__s.time_since_epoch().count()),
    177   1.5  mrg 	    static_cast<long>(__ns.count())
    178   1.5  mrg 	  };
    179   1.5  mrg 
    180   1.6  mrg 	  return static_cast<_Derived*>(this)->_M_timedlock(__ts);
    181   1.5  mrg 	}
    182   1.5  mrg 
    183  1.11  mrg #ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
    184  1.11  mrg       template<typename _Duration>
    185  1.11  mrg 	bool
    186  1.11  mrg 	_M_try_lock_until(const chrono::time_point<chrono::steady_clock,
    187  1.11  mrg 						   _Duration>& __atime)
    188  1.11  mrg 	{
    189  1.11  mrg 	  auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
    190  1.11  mrg 	  auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
    191  1.11  mrg 
    192  1.11  mrg 	  __gthread_time_t __ts = {
    193  1.11  mrg 	    static_cast<std::time_t>(__s.time_since_epoch().count()),
    194  1.11  mrg 	    static_cast<long>(__ns.count())
    195  1.11  mrg 	  };
    196  1.11  mrg 
    197  1.11  mrg 	  return static_cast<_Derived*>(this)->_M_clocklock(CLOCK_MONOTONIC,
    198  1.11  mrg 							    __ts);
    199  1.11  mrg 	}
    200  1.11  mrg #endif
    201  1.11  mrg 
    202   1.5  mrg       template<typename _Clock, typename _Duration>
    203   1.5  mrg 	bool
    204   1.5  mrg 	_M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
    205   1.5  mrg 	{
    206  1.11  mrg #if __cplusplus > 201703L
    207  1.11  mrg 	  static_assert(chrono::is_clock_v<_Clock>);
    208  1.11  mrg #endif
    209  1.11  mrg 	  // The user-supplied clock may not tick at the same rate as
    210  1.11  mrg 	  // steady_clock, so we must loop in order to guarantee that
    211  1.11  mrg 	  // the timeout has expired before returning false.
    212  1.11  mrg 	  auto __now = _Clock::now();
    213  1.11  mrg 	  do {
    214  1.11  mrg 	    auto __rtime = __atime - __now;
    215  1.11  mrg 	    if (_M_try_lock_for(__rtime))
    216  1.11  mrg 	      return true;
    217  1.11  mrg 	    __now = _Clock::now();
    218  1.11  mrg 	  } while (__atime > __now);
    219  1.11  mrg 	  return false;
    220   1.5  mrg 	}
    221   1.5  mrg     };
    222  1.12  mrg   /// @endcond
    223   1.5  mrg 
    224  1.12  mrg   /** The standard timed mutex type.
    225  1.12  mrg    *
    226  1.12  mrg    * A non-recursive mutex that supports a timeout when trying to acquire the
    227  1.12  mrg    * lock.
    228  1.12  mrg    *
    229  1.12  mrg    * @headerfile mutex
    230  1.12  mrg    * @since C++11
    231  1.12  mrg    */
    232   1.5  mrg   class timed_mutex
    233   1.5  mrg   : private __mutex_base, public __timed_mutex_impl<timed_mutex>
    234   1.1  mrg   {
    235   1.1  mrg   public:
    236   1.1  mrg     typedef __native_type* 		  	native_handle_type;
    237   1.1  mrg 
    238   1.3  mrg     timed_mutex() = default;
    239   1.3  mrg     ~timed_mutex() = default;
    240   1.1  mrg 
    241   1.1  mrg     timed_mutex(const timed_mutex&) = delete;
    242   1.1  mrg     timed_mutex& operator=(const timed_mutex&) = delete;
    243   1.1  mrg 
    244   1.1  mrg     void
    245   1.1  mrg     lock()
    246   1.1  mrg     {
    247   1.1  mrg       int __e = __gthread_mutex_lock(&_M_mutex);
    248   1.1  mrg 
    249   1.1  mrg       // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
    250   1.1  mrg       if (__e)
    251   1.1  mrg 	__throw_system_error(__e);
    252   1.1  mrg     }
    253   1.1  mrg 
    254   1.1  mrg     bool
    255   1.3  mrg     try_lock() noexcept
    256   1.1  mrg     {
    257   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    258   1.1  mrg       return !__gthread_mutex_trylock(&_M_mutex);
    259   1.1  mrg     }
    260   1.1  mrg 
    261   1.1  mrg     template <class _Rep, class _Period>
    262   1.1  mrg       bool
    263   1.1  mrg       try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
    264   1.3  mrg       { return _M_try_lock_for(__rtime); }
    265   1.1  mrg 
    266   1.1  mrg     template <class _Clock, class _Duration>
    267   1.1  mrg       bool
    268   1.1  mrg       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
    269   1.3  mrg       { return _M_try_lock_until(__atime); }
    270   1.1  mrg 
    271   1.1  mrg     void
    272   1.1  mrg     unlock()
    273   1.1  mrg     {
    274   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    275   1.1  mrg       __gthread_mutex_unlock(&_M_mutex);
    276   1.1  mrg     }
    277   1.1  mrg 
    278   1.1  mrg     native_handle_type
    279   1.8  mrg     native_handle() noexcept
    280   1.1  mrg     { return &_M_mutex; }
    281   1.6  mrg 
    282   1.6  mrg     private:
    283   1.6  mrg       friend class __timed_mutex_impl<timed_mutex>;
    284   1.6  mrg 
    285   1.6  mrg       bool
    286   1.6  mrg       _M_timedlock(const __gthread_time_t& __ts)
    287   1.6  mrg       { return !__gthread_mutex_timedlock(&_M_mutex, &__ts); }
    288  1.11  mrg 
    289  1.11  mrg #if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
    290  1.11  mrg       bool
    291  1.12  mrg       _M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
    292  1.12  mrg       { return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
    293  1.11  mrg #endif
    294   1.1  mrg   };
    295   1.1  mrg 
    296  1.12  mrg   /** The standard recursive timed mutex type.
    297  1.12  mrg    *
    298  1.12  mrg    * A recursive mutex that supports a timeout when trying to acquire the
    299  1.12  mrg    * lock. A recursive mutex can be locked more than once by the same thread.
    300  1.12  mrg    * Other threads cannot lock the mutex until the owning thread unlocks it
    301  1.12  mrg    * as many times as it was locked.
    302  1.12  mrg    *
    303  1.12  mrg    * @headerfile mutex
    304  1.12  mrg    * @since C++11
    305  1.12  mrg    */
    306   1.5  mrg   class recursive_timed_mutex
    307   1.5  mrg   : private __recursive_mutex_base,
    308   1.5  mrg     public __timed_mutex_impl<recursive_timed_mutex>
    309   1.1  mrg   {
    310   1.1  mrg   public:
    311   1.1  mrg     typedef __native_type* 			native_handle_type;
    312   1.1  mrg 
    313   1.3  mrg     recursive_timed_mutex() = default;
    314   1.3  mrg     ~recursive_timed_mutex() = default;
    315   1.1  mrg 
    316   1.1  mrg     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    317   1.1  mrg     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
    318   1.1  mrg 
    319   1.1  mrg     void
    320   1.1  mrg     lock()
    321   1.1  mrg     {
    322   1.1  mrg       int __e = __gthread_recursive_mutex_lock(&_M_mutex);
    323   1.1  mrg 
    324   1.1  mrg       // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
    325   1.1  mrg       if (__e)
    326   1.1  mrg 	__throw_system_error(__e);
    327   1.1  mrg     }
    328   1.1  mrg 
    329   1.1  mrg     bool
    330   1.3  mrg     try_lock() noexcept
    331   1.1  mrg     {
    332   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    333   1.1  mrg       return !__gthread_recursive_mutex_trylock(&_M_mutex);
    334   1.1  mrg     }
    335   1.1  mrg 
    336   1.1  mrg     template <class _Rep, class _Period>
    337   1.1  mrg       bool
    338   1.1  mrg       try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
    339   1.3  mrg       { return _M_try_lock_for(__rtime); }
    340   1.1  mrg 
    341   1.1  mrg     template <class _Clock, class _Duration>
    342   1.1  mrg       bool
    343   1.1  mrg       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
    344   1.3  mrg       { return _M_try_lock_until(__atime); }
    345   1.1  mrg 
    346   1.1  mrg     void
    347   1.1  mrg     unlock()
    348   1.1  mrg     {
    349   1.1  mrg       // XXX EINVAL, EAGAIN, EBUSY
    350   1.1  mrg       __gthread_recursive_mutex_unlock(&_M_mutex);
    351   1.1  mrg     }
    352   1.1  mrg 
    353   1.1  mrg     native_handle_type
    354   1.8  mrg     native_handle() noexcept
    355   1.1  mrg     { return &_M_mutex; }
    356   1.6  mrg 
    357   1.6  mrg     private:
    358   1.6  mrg       friend class __timed_mutex_impl<recursive_timed_mutex>;
    359   1.6  mrg 
    360   1.6  mrg       bool
    361   1.6  mrg       _M_timedlock(const __gthread_time_t& __ts)
    362   1.6  mrg       { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }
    363  1.11  mrg 
    364  1.11  mrg #ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
    365  1.11  mrg       bool
    366  1.12  mrg       _M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
    367  1.12  mrg       { return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
    368  1.11  mrg #endif
    369   1.1  mrg   };
    370   1.1  mrg 
    371   1.6  mrg #else // !_GTHREAD_USE_MUTEX_TIMEDLOCK
    372   1.1  mrg 
    373   1.6  mrg   /// timed_mutex
    374   1.6  mrg   class timed_mutex
    375   1.6  mrg   {
    376   1.6  mrg     mutex		_M_mut;
    377   1.6  mrg     condition_variable	_M_cv;
    378   1.6  mrg     bool		_M_locked = false;
    379   1.1  mrg 
    380   1.6  mrg   public:
    381   1.1  mrg 
    382   1.6  mrg     timed_mutex() = default;
    383   1.6  mrg     ~timed_mutex() { __glibcxx_assert( !_M_locked ); }
    384   1.5  mrg 
    385   1.6  mrg     timed_mutex(const timed_mutex&) = delete;
    386   1.6  mrg     timed_mutex& operator=(const timed_mutex&) = delete;
    387   1.5  mrg 
    388   1.6  mrg     void
    389   1.6  mrg     lock()
    390   1.6  mrg     {
    391   1.6  mrg       unique_lock<mutex> __lk(_M_mut);
    392   1.6  mrg       _M_cv.wait(__lk, [&]{ return !_M_locked; });
    393   1.6  mrg       _M_locked = true;
    394   1.6  mrg     }
    395   1.1  mrg 
    396   1.6  mrg     bool
    397   1.6  mrg     try_lock()
    398   1.1  mrg     {
    399   1.6  mrg       lock_guard<mutex> __lk(_M_mut);
    400   1.6  mrg       if (_M_locked)
    401   1.6  mrg 	return false;
    402   1.6  mrg       _M_locked = true;
    403   1.6  mrg       return true;
    404   1.6  mrg     }
    405   1.1  mrg 
    406   1.6  mrg     template<typename _Rep, typename _Period>
    407   1.6  mrg       bool
    408   1.6  mrg       try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
    409   1.1  mrg       {
    410   1.6  mrg 	unique_lock<mutex> __lk(_M_mut);
    411   1.6  mrg 	if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; }))
    412   1.6  mrg 	  return false;
    413   1.6  mrg 	_M_locked = true;
    414   1.6  mrg 	return true;
    415   1.1  mrg       }
    416   1.1  mrg 
    417   1.6  mrg     template<typename _Clock, typename _Duration>
    418   1.6  mrg       bool
    419   1.6  mrg       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
    420   1.1  mrg       {
    421   1.6  mrg 	unique_lock<mutex> __lk(_M_mut);
    422   1.6  mrg 	if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; }))
    423   1.6  mrg 	  return false;
    424   1.6  mrg 	_M_locked = true;
    425   1.6  mrg 	return true;
    426   1.1  mrg       }
    427   1.1  mrg 
    428   1.6  mrg     void
    429   1.6  mrg     unlock()
    430   1.6  mrg     {
    431   1.6  mrg       lock_guard<mutex> __lk(_M_mut);
    432   1.6  mrg       __glibcxx_assert( _M_locked );
    433   1.6  mrg       _M_locked = false;
    434   1.6  mrg       _M_cv.notify_one();
    435   1.6  mrg     }
    436   1.6  mrg   };
    437   1.1  mrg 
    438   1.6  mrg   /// recursive_timed_mutex
    439   1.6  mrg   class recursive_timed_mutex
    440   1.6  mrg   {
    441   1.6  mrg     mutex		_M_mut;
    442   1.6  mrg     condition_variable	_M_cv;
    443   1.6  mrg     thread::id		_M_owner;
    444   1.6  mrg     unsigned		_M_count = 0;
    445   1.1  mrg 
    446   1.6  mrg     // Predicate type that tests whether the current thread can lock a mutex.
    447   1.6  mrg     struct _Can_lock
    448   1.6  mrg     {
    449   1.6  mrg       // Returns true if the mutex is unlocked or is locked by _M_caller.
    450   1.6  mrg       bool
    451   1.6  mrg       operator()() const noexcept
    452   1.6  mrg       { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; }
    453   1.1  mrg 
    454   1.6  mrg       const recursive_timed_mutex* _M_mx;
    455   1.6  mrg       thread::id _M_caller;
    456   1.6  mrg     };
    457   1.1  mrg 
    458   1.6  mrg   public:
    459   1.1  mrg 
    460   1.6  mrg     recursive_timed_mutex() = default;
    461   1.6  mrg     ~recursive_timed_mutex() { __glibcxx_assert( _M_count == 0 ); }
    462   1.1  mrg 
    463   1.6  mrg     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    464   1.6  mrg     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
    465   1.1  mrg 
    466   1.6  mrg     void
    467   1.6  mrg     lock()
    468   1.6  mrg     {
    469   1.6  mrg       auto __id = this_thread::get_id();
    470   1.6  mrg       _Can_lock __can_lock{this, __id};
    471   1.6  mrg       unique_lock<mutex> __lk(_M_mut);
    472   1.6  mrg       _M_cv.wait(__lk, __can_lock);
    473   1.6  mrg       if (_M_count == -1u)
    474   1.6  mrg 	__throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3
    475   1.6  mrg       _M_owner = __id;
    476   1.6  mrg       ++_M_count;
    477   1.6  mrg     }
    478   1.1  mrg 
    479   1.6  mrg     bool
    480   1.6  mrg     try_lock()
    481   1.6  mrg     {
    482   1.6  mrg       auto __id = this_thread::get_id();
    483   1.6  mrg       _Can_lock __can_lock{this, __id};
    484   1.6  mrg       lock_guard<mutex> __lk(_M_mut);
    485   1.6  mrg       if (!__can_lock())
    486   1.6  mrg 	return false;
    487   1.6  mrg       if (_M_count == -1u)
    488   1.6  mrg 	return false;
    489   1.6  mrg       _M_owner = __id;
    490   1.6  mrg       ++_M_count;
    491   1.6  mrg       return true;
    492   1.6  mrg     }
    493   1.1  mrg 
    494   1.6  mrg     template<typename _Rep, typename _Period>
    495   1.6  mrg       bool
    496   1.6  mrg       try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
    497   1.1  mrg       {
    498   1.6  mrg 	auto __id = this_thread::get_id();
    499   1.6  mrg 	_Can_lock __can_lock{this, __id};
    500   1.6  mrg 	unique_lock<mutex> __lk(_M_mut);
    501   1.6  mrg 	if (!_M_cv.wait_for(__lk, __rtime, __can_lock))
    502   1.6  mrg 	  return false;
    503   1.6  mrg 	if (_M_count == -1u)
    504   1.6  mrg 	  return false;
    505   1.6  mrg 	_M_owner = __id;
    506   1.6  mrg 	++_M_count;
    507   1.6  mrg 	return true;
    508   1.1  mrg       }
    509   1.1  mrg 
    510   1.6  mrg     template<typename _Clock, typename _Duration>
    511   1.1  mrg       bool
    512   1.6  mrg       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
    513   1.1  mrg       {
    514   1.6  mrg 	auto __id = this_thread::get_id();
    515   1.6  mrg 	_Can_lock __can_lock{this, __id};
    516   1.6  mrg 	unique_lock<mutex> __lk(_M_mut);
    517   1.6  mrg 	if (!_M_cv.wait_until(__lk, __atime, __can_lock))
    518   1.6  mrg 	  return false;
    519   1.6  mrg 	if (_M_count == -1u)
    520   1.6  mrg 	  return false;
    521   1.6  mrg 	_M_owner = __id;
    522   1.6  mrg 	++_M_count;
    523   1.6  mrg 	return true;
    524   1.1  mrg       }
    525   1.1  mrg 
    526   1.6  mrg     void
    527   1.6  mrg     unlock()
    528   1.6  mrg     {
    529   1.6  mrg       lock_guard<mutex> __lk(_M_mut);
    530   1.6  mrg       __glibcxx_assert( _M_owner == this_thread::get_id() );
    531   1.6  mrg       __glibcxx_assert( _M_count > 0 );
    532   1.6  mrg       if (--_M_count == 0)
    533   1.1  mrg 	{
    534   1.6  mrg 	  _M_owner = {};
    535   1.6  mrg 	  _M_cv.notify_one();
    536   1.1  mrg 	}
    537   1.6  mrg     }
    538   1.6  mrg   };
    539   1.1  mrg 
    540   1.6  mrg #endif
    541   1.6  mrg #endif // _GLIBCXX_HAS_GTHREADS
    542   1.1  mrg 
    543  1.11  mrg   /// @cond undocumented
    544  1.12  mrg   namespace __detail
    545  1.12  mrg   {
    546  1.12  mrg     // Lock the last lockable, after all previous ones are locked.
    547  1.12  mrg     template<typename _Lockable>
    548  1.12  mrg       inline int
    549  1.12  mrg       __try_lock_impl(_Lockable& __l)
    550  1.12  mrg       {
    551  1.12  mrg 	if (unique_lock<_Lockable> __lock{__l, try_to_lock})
    552  1.12  mrg 	  {
    553  1.12  mrg 	    __lock.release();
    554  1.12  mrg 	    return -1;
    555  1.12  mrg 	  }
    556  1.12  mrg 	else
    557  1.12  mrg 	  return 0;
    558  1.12  mrg       }
    559  1.12  mrg 
    560  1.12  mrg     // Lock each lockable in turn.
    561  1.12  mrg     // Use iteration if all lockables are the same type, recursion otherwise.
    562  1.12  mrg     template<typename _L0, typename... _Lockables>
    563  1.12  mrg       inline int
    564  1.12  mrg       __try_lock_impl(_L0& __l0, _Lockables&... __lockables)
    565  1.12  mrg       {
    566  1.12  mrg #if __cplusplus >= 201703L
    567  1.12  mrg 	if constexpr ((is_same_v<_L0, _Lockables> && ...))
    568  1.12  mrg 	  {
    569  1.12  mrg 	    constexpr int _Np = 1 + sizeof...(_Lockables);
    570  1.12  mrg 	    unique_lock<_L0> __locks[_Np] = {
    571  1.12  mrg 		{__l0, defer_lock}, {__lockables, defer_lock}...
    572  1.12  mrg 	    };
    573  1.12  mrg 	    for (int __i = 0; __i < _Np; ++__i)
    574  1.12  mrg 	      {
    575  1.12  mrg 		if (!__locks[__i].try_lock())
    576  1.12  mrg 		  {
    577  1.12  mrg 		    const int __failed = __i;
    578  1.12  mrg 		    while (__i--)
    579  1.12  mrg 		      __locks[__i].unlock();
    580  1.12  mrg 		    return __failed;
    581  1.12  mrg 		  }
    582  1.12  mrg 	      }
    583  1.12  mrg 	    for (auto& __l : __locks)
    584  1.12  mrg 	      __l.release();
    585  1.12  mrg 	    return -1;
    586  1.12  mrg 	  }
    587  1.12  mrg 	else
    588  1.12  mrg #endif
    589  1.12  mrg 	if (unique_lock<_L0> __lock{__l0, try_to_lock})
    590  1.12  mrg 	  {
    591  1.12  mrg 	    int __idx = __detail::__try_lock_impl(__lockables...);
    592  1.12  mrg 	    if (__idx == -1)
    593  1.12  mrg 	      {
    594  1.12  mrg 		__lock.release();
    595  1.12  mrg 		return -1;
    596  1.12  mrg 	      }
    597  1.12  mrg 	    return __idx + 1;
    598  1.12  mrg 	  }
    599  1.12  mrg 	else
    600  1.12  mrg 	  return 0;
    601  1.12  mrg       }
    602   1.1  mrg 
    603  1.12  mrg   } // namespace __detail
    604  1.11  mrg   /// @endcond
    605   1.1  mrg 
    606   1.1  mrg   /** @brief Generic try_lock.
    607   1.9  mrg    *  @param __l1 Meets Lockable requirements (try_lock() may throw).
    608   1.9  mrg    *  @param __l2 Meets Lockable requirements (try_lock() may throw).
    609   1.9  mrg    *  @param __l3 Meets Lockable requirements (try_lock() may throw).
    610   1.1  mrg    *  @return Returns -1 if all try_lock() calls return true. Otherwise returns
    611   1.1  mrg    *          a 0-based index corresponding to the argument that returned false.
    612   1.1  mrg    *  @post Either all arguments are locked, or none will be.
    613   1.1  mrg    *
    614   1.1  mrg    *  Sequentially calls try_lock() on each argument.
    615   1.1  mrg    */
    616  1.12  mrg   template<typename _L1, typename _L2, typename... _L3>
    617  1.12  mrg     inline int
    618  1.12  mrg     try_lock(_L1& __l1, _L2& __l2, _L3&... __l3)
    619  1.12  mrg     {
    620  1.12  mrg       return __detail::__try_lock_impl(__l1, __l2, __l3...);
    621   1.1  mrg     }
    622   1.1  mrg 
    623  1.12  mrg   /// @cond undocumented
    624  1.12  mrg   namespace __detail
    625  1.12  mrg   {
    626  1.12  mrg     // This function can recurse up to N levels deep, for N = 1+sizeof...(L1).
    627  1.12  mrg     // On each recursion the lockables are rotated left one position,
    628  1.12  mrg     // e.g. depth 0: l0, l1, l2; depth 1: l1, l2, l0; depth 2: l2, l0, l1.
    629  1.12  mrg     // When a call to l_i.try_lock() fails it recurses/returns to depth=i
    630  1.12  mrg     // so that l_i is the first argument, and then blocks until l_i is locked.
    631  1.12  mrg     template<typename _L0, typename... _L1>
    632  1.12  mrg       void
    633  1.12  mrg       __lock_impl(int& __i, int __depth, _L0& __l0, _L1&... __l1)
    634  1.12  mrg       {
    635  1.12  mrg 	while (__i >= __depth)
    636  1.12  mrg 	  {
    637  1.12  mrg 	    if (__i == __depth)
    638  1.12  mrg 	      {
    639  1.12  mrg 		int __failed = 1; // index that couldn't be locked
    640  1.12  mrg 		{
    641  1.12  mrg 		  unique_lock<_L0> __first(__l0);
    642  1.12  mrg 		  __failed += __detail::__try_lock_impl(__l1...);
    643  1.12  mrg 		  if (!__failed)
    644  1.12  mrg 		    {
    645  1.12  mrg 		      __i = -1; // finished
    646  1.12  mrg 		      __first.release();
    647  1.12  mrg 		      return;
    648  1.12  mrg 		    }
    649  1.12  mrg 		}
    650  1.12  mrg #if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
    651  1.12  mrg 		__gthread_yield();
    652  1.12  mrg #endif
    653  1.12  mrg 		constexpr auto __n = 1 + sizeof...(_L1);
    654  1.12  mrg 		__i = (__depth + __failed) % __n;
    655  1.12  mrg 	      }
    656  1.12  mrg 	    else // rotate left until l_i is first.
    657  1.12  mrg 	      __detail::__lock_impl(__i, __depth + 1, __l1..., __l0);
    658  1.12  mrg 	  }
    659  1.12  mrg       }
    660  1.12  mrg 
    661  1.12  mrg   } // namespace __detail
    662  1.12  mrg   /// @endcond
    663  1.12  mrg 
    664   1.3  mrg   /** @brief Generic lock.
    665   1.9  mrg    *  @param __l1 Meets Lockable requirements (try_lock() may throw).
    666   1.9  mrg    *  @param __l2 Meets Lockable requirements (try_lock() may throw).
    667   1.9  mrg    *  @param __l3 Meets Lockable requirements (try_lock() may throw).
    668   1.3  mrg    *  @throw An exception thrown by an argument's lock() or try_lock() member.
    669   1.3  mrg    *  @post All arguments are locked.
    670   1.3  mrg    *
    671   1.3  mrg    *  All arguments are locked via a sequence of calls to lock(), try_lock()
    672  1.12  mrg    *  and unlock().  If this function exits via an exception any locks that
    673  1.12  mrg    *  were obtained will be released.
    674   1.3  mrg    */
    675   1.5  mrg   template<typename _L1, typename _L2, typename... _L3>
    676   1.1  mrg     void
    677   1.3  mrg     lock(_L1& __l1, _L2& __l2, _L3&... __l3)
    678   1.3  mrg     {
    679  1.12  mrg #if __cplusplus >= 201703L
    680  1.12  mrg       if constexpr (is_same_v<_L1, _L2> && (is_same_v<_L1, _L3> && ...))
    681  1.12  mrg 	{
    682  1.12  mrg 	  constexpr int _Np = 2 + sizeof...(_L3);
    683  1.12  mrg 	  unique_lock<_L1> __locks[] = {
    684  1.12  mrg 	      {__l1, defer_lock}, {__l2, defer_lock}, {__l3, defer_lock}...
    685  1.12  mrg 	  };
    686  1.12  mrg 	  int __first = 0;
    687  1.12  mrg 	  do {
    688  1.12  mrg 	    __locks[__first].lock();
    689  1.12  mrg 	    for (int __j = 1; __j < _Np; ++__j)
    690  1.12  mrg 	      {
    691  1.12  mrg 		const int __idx = (__first + __j) % _Np;
    692  1.12  mrg 		if (!__locks[__idx].try_lock())
    693  1.12  mrg 		  {
    694  1.12  mrg 		    for (int __k = __j; __k != 0; --__k)
    695  1.12  mrg 		      __locks[(__first + __k - 1) % _Np].unlock();
    696  1.12  mrg 		    __first = __idx;
    697  1.12  mrg 		    break;
    698  1.12  mrg 		  }
    699  1.12  mrg 	      }
    700  1.12  mrg 	  } while (!__locks[__first].owns_lock());
    701  1.12  mrg 
    702  1.12  mrg 	  for (auto& __l : __locks)
    703  1.12  mrg 	    __l.release();
    704  1.12  mrg 	}
    705  1.12  mrg       else
    706  1.12  mrg #endif
    707  1.12  mrg 	{
    708  1.12  mrg 	  int __i = 0;
    709  1.12  mrg 	  __detail::__lock_impl(__i, 0, __l1, __l2, __l3...);
    710  1.12  mrg 	}
    711   1.3  mrg     }
    712   1.1  mrg 
    713   1.8  mrg #if __cplusplus >= 201703L
    714  1.12  mrg #define __cpp_lib_scoped_lock 201703L
    715   1.8  mrg   /** @brief A scoped lock type for multiple lockable objects.
    716   1.8  mrg    *
    717   1.8  mrg    * A scoped_lock controls mutex ownership within a scope, releasing
    718   1.8  mrg    * ownership in the destructor.
    719  1.12  mrg    *
    720  1.12  mrg    * @headerfile mutex
    721  1.12  mrg    * @since C++17
    722   1.8  mrg    */
    723   1.8  mrg   template<typename... _MutexTypes>
    724   1.8  mrg     class scoped_lock
    725   1.8  mrg     {
    726   1.8  mrg     public:
    727   1.8  mrg       explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...))
    728   1.8  mrg       { std::lock(__m...); }
    729   1.8  mrg 
    730   1.8  mrg       explicit scoped_lock(adopt_lock_t, _MutexTypes&... __m) noexcept
    731   1.8  mrg       : _M_devices(std::tie(__m...))
    732   1.8  mrg       { } // calling thread owns mutex
    733   1.8  mrg 
    734   1.8  mrg       ~scoped_lock()
    735  1.11  mrg       { std::apply([](auto&... __m) { (__m.unlock(), ...); }, _M_devices); }
    736   1.8  mrg 
    737   1.8  mrg       scoped_lock(const scoped_lock&) = delete;
    738   1.8  mrg       scoped_lock& operator=(const scoped_lock&) = delete;
    739   1.8  mrg 
    740   1.8  mrg     private:
    741   1.8  mrg       tuple<_MutexTypes&...> _M_devices;
    742   1.8  mrg     };
    743   1.8  mrg 
    744   1.8  mrg   template<>
    745   1.8  mrg     class scoped_lock<>
    746   1.8  mrg     {
    747   1.8  mrg     public:
    748   1.8  mrg       explicit scoped_lock() = default;
    749   1.8  mrg       explicit scoped_lock(adopt_lock_t) noexcept { }
    750   1.8  mrg       ~scoped_lock() = default;
    751   1.8  mrg 
    752   1.8  mrg       scoped_lock(const scoped_lock&) = delete;
    753   1.8  mrg       scoped_lock& operator=(const scoped_lock&) = delete;
    754   1.8  mrg     };
    755   1.8  mrg 
    756   1.8  mrg   template<typename _Mutex>
    757   1.8  mrg     class scoped_lock<_Mutex>
    758   1.8  mrg     {
    759   1.8  mrg     public:
    760   1.8  mrg       using mutex_type = _Mutex;
    761   1.8  mrg 
    762   1.8  mrg       explicit scoped_lock(mutex_type& __m) : _M_device(__m)
    763   1.8  mrg       { _M_device.lock(); }
    764   1.8  mrg 
    765   1.8  mrg       explicit scoped_lock(adopt_lock_t, mutex_type& __m) noexcept
    766   1.8  mrg       : _M_device(__m)
    767   1.8  mrg       { } // calling thread owns mutex
    768   1.8  mrg 
    769   1.8  mrg       ~scoped_lock()
    770   1.8  mrg       { _M_device.unlock(); }
    771   1.8  mrg 
    772   1.8  mrg       scoped_lock(const scoped_lock&) = delete;
    773   1.8  mrg       scoped_lock& operator=(const scoped_lock&) = delete;
    774   1.8  mrg 
    775   1.8  mrg     private:
    776   1.8  mrg       mutex_type&  _M_device;
    777   1.8  mrg     };
    778   1.8  mrg #endif // C++17
    779   1.8  mrg 
    780   1.3  mrg #ifdef _GLIBCXX_HAS_GTHREADS
    781  1.11  mrg   /// Flag type used by std::call_once
    782   1.1  mrg   struct once_flag
    783   1.1  mrg   {
    784   1.3  mrg     constexpr once_flag() noexcept = default;
    785   1.1  mrg 
    786   1.3  mrg     /// Deleted copy constructor
    787   1.1  mrg     once_flag(const once_flag&) = delete;
    788   1.3  mrg     /// Deleted assignment operator
    789   1.1  mrg     once_flag& operator=(const once_flag&) = delete;
    790   1.1  mrg 
    791  1.12  mrg   private:
    792  1.12  mrg     // For gthreads targets a pthread_once_t is used with pthread_once, but
    793  1.12  mrg     // for most targets this doesn't work correctly for exceptional executions.
    794  1.12  mrg     __gthread_once_t _M_once = __GTHREAD_ONCE_INIT;
    795  1.12  mrg 
    796  1.12  mrg     struct _Prepare_execution;
    797  1.12  mrg 
    798   1.1  mrg     template<typename _Callable, typename... _Args>
    799   1.1  mrg       friend void
    800   1.3  mrg       call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
    801   1.1  mrg   };
    802   1.1  mrg 
    803  1.11  mrg   /// @cond undocumented
    804  1.12  mrg # ifdef _GLIBCXX_HAVE_TLS
    805  1.12  mrg   // If TLS is available use thread-local state for the type-erased callable
    806  1.12  mrg   // that is being run by std::call_once in the current thread.
    807   1.1  mrg   extern __thread void* __once_callable;
    808   1.1  mrg   extern __thread void (*__once_call)();
    809  1.12  mrg 
    810  1.12  mrg   // RAII type to set up state for pthread_once call.
    811  1.12  mrg   struct once_flag::_Prepare_execution
    812  1.12  mrg   {
    813  1.12  mrg     template<typename _Callable>
    814  1.12  mrg       explicit
    815  1.12  mrg       _Prepare_execution(_Callable& __c)
    816  1.12  mrg       {
    817  1.12  mrg 	// Store address in thread-local pointer:
    818  1.12  mrg 	__once_callable = std::__addressof(__c);
    819  1.12  mrg 	// Trampoline function to invoke the closure via thread-local pointer:
    820  1.12  mrg 	__once_call = [] { (*static_cast<_Callable*>(__once_callable))(); };
    821  1.12  mrg       }
    822  1.12  mrg 
    823  1.12  mrg     ~_Prepare_execution()
    824  1.12  mrg     {
    825  1.12  mrg       // PR libstdc++/82481
    826  1.12  mrg       __once_callable = nullptr;
    827  1.12  mrg       __once_call = nullptr;
    828  1.12  mrg     }
    829  1.12  mrg 
    830  1.12  mrg     _Prepare_execution(const _Prepare_execution&) = delete;
    831  1.12  mrg     _Prepare_execution& operator=(const _Prepare_execution&) = delete;
    832  1.12  mrg   };
    833  1.12  mrg 
    834  1.12  mrg # else
    835  1.12  mrg   // Without TLS use a global std::mutex and store the callable in a
    836  1.12  mrg   // global std::function.
    837   1.1  mrg   extern function<void()> __once_functor;
    838   1.1  mrg 
    839   1.1  mrg   extern void
    840   1.1  mrg   __set_once_functor_lock_ptr(unique_lock<mutex>*);
    841   1.1  mrg 
    842   1.1  mrg   extern mutex&
    843   1.1  mrg   __get_once_mutex();
    844   1.1  mrg 
    845  1.12  mrg   // RAII type to set up state for pthread_once call.
    846  1.12  mrg   struct once_flag::_Prepare_execution
    847  1.12  mrg   {
    848  1.12  mrg     template<typename _Callable>
    849  1.12  mrg       explicit
    850  1.12  mrg       _Prepare_execution(_Callable& __c)
    851  1.12  mrg       {
    852  1.12  mrg 	// Store the callable in the global std::function
    853  1.12  mrg 	__once_functor = __c;
    854  1.12  mrg 	__set_once_functor_lock_ptr(&_M_functor_lock);
    855  1.12  mrg       }
    856  1.12  mrg 
    857  1.12  mrg     ~_Prepare_execution()
    858  1.12  mrg     {
    859  1.12  mrg       if (_M_functor_lock)
    860  1.12  mrg 	__set_once_functor_lock_ptr(nullptr);
    861  1.12  mrg     }
    862  1.12  mrg 
    863  1.12  mrg   private:
    864  1.12  mrg     // XXX This deadlocks if used recursively (PR 97949)
    865  1.12  mrg     unique_lock<mutex> _M_functor_lock{__get_once_mutex()};
    866  1.12  mrg 
    867  1.12  mrg     _Prepare_execution(const _Prepare_execution&) = delete;
    868  1.12  mrg     _Prepare_execution& operator=(const _Prepare_execution&) = delete;
    869  1.12  mrg   };
    870  1.12  mrg # endif
    871  1.12  mrg   /// @endcond
    872  1.12  mrg 
    873  1.12  mrg   // This function is passed to pthread_once by std::call_once.
    874  1.12  mrg   // It runs __once_call() or __once_functor().
    875   1.3  mrg   extern "C" void __once_proxy(void);
    876   1.1  mrg 
    877  1.11  mrg   /// Invoke a callable and synchronize with other calls using the same flag
    878   1.1  mrg   template<typename _Callable, typename... _Args>
    879   1.1  mrg     void
    880   1.3  mrg     call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
    881   1.1  mrg     {
    882  1.12  mrg       // Closure type that runs the function
    883   1.6  mrg       auto __callable = [&] {
    884   1.6  mrg 	  std::__invoke(std::forward<_Callable>(__f),
    885   1.6  mrg 			std::forward<_Args>(__args)...);
    886   1.6  mrg       };
    887   1.1  mrg 
    888  1.12  mrg       once_flag::_Prepare_execution __exec(__callable);
    889  1.12  mrg 
    890  1.12  mrg       // XXX pthread_once does not reset the flag if an exception is thrown.
    891  1.12  mrg       if (int __e = __gthread_once(&__once._M_once, &__once_proxy))
    892  1.12  mrg 	__throw_system_error(__e);
    893  1.12  mrg     }
    894  1.12  mrg 
    895  1.12  mrg #else // _GLIBCXX_HAS_GTHREADS
    896  1.12  mrg 
    897  1.12  mrg   /// Flag type used by std::call_once
    898  1.12  mrg   struct once_flag
    899  1.12  mrg   {
    900  1.12  mrg     constexpr once_flag() noexcept = default;
    901  1.12  mrg 
    902  1.12  mrg     /// Deleted copy constructor
    903  1.12  mrg     once_flag(const once_flag&) = delete;
    904  1.12  mrg     /// Deleted assignment operator
    905  1.12  mrg     once_flag& operator=(const once_flag&) = delete;
    906  1.12  mrg 
    907  1.12  mrg   private:
    908  1.12  mrg     // There are two different std::once_flag interfaces, abstracting four
    909  1.12  mrg     // different implementations.
    910  1.12  mrg     // The single-threaded interface uses the _M_activate() and _M_finish(bool)
    911  1.12  mrg     // functions, which start and finish an active execution respectively.
    912  1.12  mrg     // See [thread.once.callonce] in C++11 for the definition of
    913  1.12  mrg     // active/passive/returning/exceptional executions.
    914  1.12  mrg     enum _Bits : int { _Init = 0, _Active = 1, _Done = 2 };
    915  1.12  mrg 
    916  1.12  mrg     int _M_once = _Bits::_Init;
    917  1.12  mrg 
    918  1.12  mrg     // Check to see if all executions will be passive now.
    919  1.12  mrg     bool
    920  1.12  mrg     _M_passive() const noexcept;
    921  1.12  mrg 
    922  1.12  mrg     // Attempts to begin an active execution.
    923  1.12  mrg     bool _M_activate();
    924  1.12  mrg 
    925  1.12  mrg     // Must be called to complete an active execution.
    926  1.12  mrg     // The argument is true if the active execution was a returning execution,
    927  1.12  mrg     // false if it was an exceptional execution.
    928  1.12  mrg     void _M_finish(bool __returning) noexcept;
    929  1.12  mrg 
    930  1.12  mrg     // RAII helper to call _M_finish.
    931  1.12  mrg     struct _Active_execution
    932  1.12  mrg     {
    933  1.12  mrg       explicit _Active_execution(once_flag& __flag) : _M_flag(__flag) { }
    934  1.12  mrg 
    935  1.12  mrg       ~_Active_execution() { _M_flag._M_finish(_M_returning); }
    936  1.12  mrg 
    937  1.12  mrg       _Active_execution(const _Active_execution&) = delete;
    938  1.12  mrg       _Active_execution& operator=(const _Active_execution&) = delete;
    939  1.12  mrg 
    940  1.12  mrg       once_flag& _M_flag;
    941  1.12  mrg       bool _M_returning = false;
    942  1.12  mrg     };
    943  1.12  mrg 
    944  1.12  mrg     template<typename _Callable, typename... _Args>
    945  1.12  mrg       friend void
    946  1.12  mrg       call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
    947  1.12  mrg   };
    948  1.12  mrg 
    949  1.12  mrg   // Inline definitions of std::once_flag members for single-threaded targets.
    950  1.12  mrg 
    951  1.12  mrg   inline bool
    952  1.12  mrg   once_flag::_M_passive() const noexcept
    953  1.12  mrg   { return _M_once == _Bits::_Done; }
    954  1.12  mrg 
    955  1.12  mrg   inline bool
    956  1.12  mrg   once_flag::_M_activate()
    957  1.12  mrg   {
    958  1.12  mrg     if (_M_once == _Bits::_Init) [[__likely__]]
    959  1.12  mrg       {
    960  1.12  mrg 	_M_once = _Bits::_Active;
    961  1.12  mrg 	return true;
    962  1.12  mrg       }
    963  1.12  mrg     else if (_M_passive()) // Caller should have checked this already.
    964  1.12  mrg       return false;
    965  1.12  mrg     else
    966  1.12  mrg       __throw_system_error(EDEADLK);
    967  1.12  mrg   }
    968  1.12  mrg 
    969  1.12  mrg   inline void
    970  1.12  mrg   once_flag::_M_finish(bool __returning) noexcept
    971  1.12  mrg   { _M_once = __returning ? _Bits::_Done : _Bits::_Init; }
    972  1.12  mrg 
    973  1.12  mrg   /// Invoke a callable and synchronize with other calls using the same flag
    974  1.12  mrg   template<typename _Callable, typename... _Args>
    975  1.12  mrg     inline void
    976  1.12  mrg     call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
    977  1.12  mrg     {
    978  1.12  mrg       if (__once._M_passive())
    979  1.12  mrg 	return;
    980  1.12  mrg       else if (__once._M_activate())
    981  1.12  mrg 	{
    982  1.12  mrg 	  once_flag::_Active_execution __exec(__once);
    983   1.1  mrg 
    984  1.12  mrg 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
    985  1.12  mrg 	  // 2442. call_once() shouldn't DECAY_COPY()
    986  1.12  mrg 	  std::__invoke(std::forward<_Callable>(__f),
    987  1.12  mrg 			std::forward<_Args>(__args)...);
    988   1.1  mrg 
    989  1.12  mrg 	  // __f(__args...) did not throw
    990  1.12  mrg 	  __exec._M_returning = true;
    991  1.12  mrg 	}
    992   1.1  mrg     }
    993   1.3  mrg #endif // _GLIBCXX_HAS_GTHREADS
    994   1.1  mrg 
    995  1.11  mrg   /// @} group mutexes
    996   1.3  mrg _GLIBCXX_END_NAMESPACE_VERSION
    997   1.3  mrg } // namespace
    998   1.1  mrg 
    999   1.3  mrg #endif // C++11
   1000   1.1  mrg 
   1001   1.1  mrg #endif // _GLIBCXX_MUTEX
   1002