// <mutex> -*- C++ -*-

// Copyright (C) 2003-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/mutex
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_MUTEX
#define _GLIBCXX_MUTEX 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/requires_hosted.h> // concurrency

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <tuple>	      // std::tuple
#include <type_traits>        // is_same_v
#include <errno.h>	      // EAGAIN, EDEADLK
#include <bits/chrono.h>      // duration, time_point, is_clock_v
#include <bits/functexcept.h> // __throw_system_error
#include <bits/invoke.h>      // __invoke
#include <bits/move.h>	      // std::forward
#include <bits/std_mutex.h>
#include <bits/unique_lock.h>
#if ! _GTHREAD_USE_MUTEX_TIMEDLOCK
# include <condition_variable>
# include <thread>
#endif
#include <ext/atomicity.h>     // __gnu_cxx::__is_single_threaded

#if defined _GLIBCXX_HAS_GTHREADS && ! defined _GLIBCXX_HAVE_TLS
# include <bits/std_function.h>  // std::function
#endif

#define __glibcxx_want_scoped_lock
#include <bits/version.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @addtogroup mutexes
   * @{
   */

#ifdef _GLIBCXX_HAS_GTHREADS
  /// @cond undocumented

  // Common base class for std::recursive_mutex and std::recursive_timed_mutex
  class __recursive_mutex_base
  {
  protected:
    typedef __gthread_recursive_mutex_t		__native_type;

    __recursive_mutex_base(const __recursive_mutex_base&) = delete;
    __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete;

#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
    __native_type  _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;

    __recursive_mutex_base() = default;
#else
    __native_type  _M_mutex;

    __recursive_mutex_base()
    {
      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
      __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
    }

    ~__recursive_mutex_base()
    { __gthread_recursive_mutex_destroy(&_M_mutex); }
#endif
  };
  /// @endcond

  /** The standard recursive mutex type.
   *
   * A recursive mutex can be locked more than once by the same thread.
   * Other threads cannot lock the mutex until the owning thread unlocks it
   * as many times as it was locked.
   *
   * @headerfile mutex
   * @since C++11
   */
  class recursive_mutex : private __recursive_mutex_base
  {
  public:
    typedef __native_type* 			native_handle_type;

    recursive_mutex() = default;
    ~recursive_mutex() = default;

    recursive_mutex(const recursive_mutex&) = delete;
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    void
    lock()
    {
      int __e = __gthread_recursive_mutex_lock(&_M_mutex);

      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
      if (__e)
	__throw_system_error(__e);
    }

    _GLIBCXX_NODISCARD
    bool
    try_lock() noexcept
    {
      // XXX EINVAL, EAGAIN, EBUSY
      return !__gthread_recursive_mutex_trylock(&_M_mutex);
    }

    void
    unlock()
    {
      // XXX EINVAL, EAGAIN, EBUSY
      __gthread_recursive_mutex_unlock(&_M_mutex);
    }

    native_handle_type
    native_handle() noexcept
    { return &_M_mutex; }
  };

#if _GTHREAD_USE_MUTEX_TIMEDLOCK
  /// @cond undocumented

  template<typename _Derived>
    class __timed_mutex_impl
    {
    protected:
      template<typename _Rep, typename _Period>
	bool
	_M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
	{
#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
	  using __clock = chrono::steady_clock;
#else
	  using __clock = chrono::system_clock;
#endif

	  auto __rt = chrono::duration_cast<__clock::duration>(__rtime);
	  if (ratio_greater<__clock::period, _Period>())
	    ++__rt;
	  return _M_try_lock_until(__clock::now() + __rt);
	}

      template<typename _Duration>
	bool
	_M_try_lock_until(const chrono::time_point<chrono::system_clock,
						   _Duration>& __atime)
	{
	  auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
	  auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);

	  __gthread_time_t __ts = {
	    static_cast<std::time_t>(__s.time_since_epoch().count()),
	    static_cast<long>(__ns.count())
	  };

	  return static_cast<_Derived*>(this)->_M_timedlock(__ts);
	}

#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
      template<typename _Duration>
	bool
	_M_try_lock_until(const chrono::time_point<chrono::steady_clock,
						   _Duration>& __atime)
	{
	  auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
	  auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);

	  __gthread_time_t __ts = {
	    static_cast<std::time_t>(__s.time_since_epoch().count()),
	    static_cast<long>(__ns.count())
	  };

	  return static_cast<_Derived*>(this)->_M_clocklock(CLOCK_MONOTONIC,
							    __ts);
	}
#endif

      template<typename _Clock, typename _Duration>
	bool
	_M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
	{
#if __cplusplus > 201703L
	  static_assert(chrono::is_clock_v<_Clock>);
#endif
	  // The user-supplied clock may not tick at the same rate as
	  // steady_clock, so we must loop in order to guarantee that
	  // the timeout has expired before returning false.
	  auto __now = _Clock::now();
	  do {
	    auto __rtime = __atime - __now;
	    if (_M_try_lock_for(__rtime))
	      return true;
	    __now = _Clock::now();
	  } while (__atime > __now);
	  return false;
	}
    };
  /// @endcond

  /** The standard timed mutex type.
   *
   * A non-recursive mutex that supports a timeout when trying to acquire the
   * lock.
   *
   * @headerfile mutex
   * @since C++11
   */
  class timed_mutex
  : private __mutex_base, public __timed_mutex_impl<timed_mutex>
  {
  public:
    typedef __native_type* 		  	native_handle_type;

    timed_mutex() = default;
    ~timed_mutex() = default;

    timed_mutex(const timed_mutex&) = delete;
    timed_mutex& operator=(const timed_mutex&) = delete;

    void
    lock()
    {
      int __e = __gthread_mutex_lock(&_M_mutex);

      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
      if (__e)
	__throw_system_error(__e);
    }

    _GLIBCXX_NODISCARD
    bool
    try_lock() noexcept
    {
      // XXX EINVAL, EAGAIN, EBUSY
      return !__gthread_mutex_trylock(&_M_mutex);
    }

    template <class _Rep, class _Period>
      _GLIBCXX_NODISCARD
      bool
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
      { return _M_try_lock_for(__rtime); }

    template <class _Clock, class _Duration>
      _GLIBCXX_NODISCARD
      bool
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
      { return _M_try_lock_until(__atime); }

    void
    unlock()
    {
      // XXX EINVAL, EAGAIN, EBUSY
      __gthread_mutex_unlock(&_M_mutex);
    }

    native_handle_type
    native_handle() noexcept
    { return &_M_mutex; }

    private:
      friend class __timed_mutex_impl<timed_mutex>;

      bool
      _M_timedlock(const __gthread_time_t& __ts)
      { return !__gthread_mutex_timedlock(&_M_mutex, &__ts); }

#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
      bool
      _M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
      { return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
#endif
  };

  /** The standard recursive timed mutex type.
   *
   * A recursive mutex that supports a timeout when trying to acquire the
   * lock. A recursive mutex can be locked more than once by the same thread.
   * Other threads cannot lock the mutex until the owning thread unlocks it
   * as many times as it was locked.
   *
   * @headerfile mutex
   * @since C++11
   */
  class recursive_timed_mutex
  : private __recursive_mutex_base,
    public __timed_mutex_impl<recursive_timed_mutex>
  {
  public:
    typedef __native_type* 			native_handle_type;

    recursive_timed_mutex() = default;
    ~recursive_timed_mutex() = default;

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

    void
    lock()
    {
      int __e = __gthread_recursive_mutex_lock(&_M_mutex);

      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
      if (__e)
	__throw_system_error(__e);
    }

    _GLIBCXX_NODISCARD
    bool
    try_lock() noexcept
    {
      // XXX EINVAL, EAGAIN, EBUSY
      return !__gthread_recursive_mutex_trylock(&_M_mutex);
    }

    template <class _Rep, class _Period>
      _GLIBCXX_NODISCARD
      bool
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
      { return _M_try_lock_for(__rtime); }

    template <class _Clock, class _Duration>
      _GLIBCXX_NODISCARD
      bool
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
      { return _M_try_lock_until(__atime); }

    void
    unlock()
    {
      // XXX EINVAL, EAGAIN, EBUSY
      __gthread_recursive_mutex_unlock(&_M_mutex);
    }

    native_handle_type
    native_handle() noexcept
    { return &_M_mutex; }

    private:
      friend class __timed_mutex_impl<recursive_timed_mutex>;

      bool
      _M_timedlock(const __gthread_time_t& __ts)
      { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }

#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
      bool
      _M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
      { return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
#endif
  };

#else // !_GTHREAD_USE_MUTEX_TIMEDLOCK

  /// timed_mutex
  class timed_mutex
  {
    mutex		_M_mut;
    condition_variable	_M_cv;
    bool		_M_locked = false;

  public:

    timed_mutex() = default;
    ~timed_mutex() { __glibcxx_assert( !_M_locked ); }

    timed_mutex(const timed_mutex&) = delete;
    timed_mutex& operator=(const timed_mutex&) = delete;

    void
    lock()
    {
      unique_lock<mutex> __lk(_M_mut);
      _M_cv.wait(__lk, [&]{ return !_M_locked; });
      _M_locked = true;
    }

    _GLIBCXX_NODISCARD
    bool
    try_lock()
    {
      lock_guard<mutex> __lk(_M_mut);
      if (_M_locked)
	return false;
      _M_locked = true;
      return true;
    }

    template<typename _Rep, typename _Period>
      _GLIBCXX_NODISCARD
      bool
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
      {
	unique_lock<mutex> __lk(_M_mut);
	if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; }))
	  return false;
	_M_locked = true;
	return true;
      }

    template<typename _Clock, typename _Duration>
      _GLIBCXX_NODISCARD
      bool
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
      {
	unique_lock<mutex> __lk(_M_mut);
	if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; }))
	  return false;
	_M_locked = true;
	return true;
      }

    void
    unlock()
    {
      lock_guard<mutex> __lk(_M_mut);
      __glibcxx_assert( _M_locked );
      _M_locked = false;
      _M_cv.notify_one();
    }
  };

  /// recursive_timed_mutex
  class recursive_timed_mutex
  {
    mutex		_M_mut;
    condition_variable	_M_cv;
    thread::id		_M_owner;
    unsigned		_M_count = 0;

    // Predicate type that tests whether the current thread can lock a mutex.
    struct _Can_lock
    {
      // Returns true if the mutex is unlocked or is locked by _M_caller.
      bool
      operator()() const noexcept
      { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; }

      const recursive_timed_mutex* _M_mx;
      thread::id _M_caller;
    };

  public:

    recursive_timed_mutex() = default;
    ~recursive_timed_mutex() { __glibcxx_assert( _M_count == 0 ); }

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

    void
    lock()
    {
      auto __id = this_thread::get_id();
      _Can_lock __can_lock{this, __id};
      unique_lock<mutex> __lk(_M_mut);
      _M_cv.wait(__lk, __can_lock);
      if (_M_count == -1u)
	__throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3
      _M_owner = __id;
      ++_M_count;
    }

    _GLIBCXX_NODISCARD
    bool
    try_lock()
    {
      auto __id = this_thread::get_id();
      _Can_lock __can_lock{this, __id};
      lock_guard<mutex> __lk(_M_mut);
      if (!__can_lock())
	return false;
      if (_M_count == -1u)
	return false;
      _M_owner = __id;
      ++_M_count;
      return true;
    }

    template<typename _Rep, typename _Period>
      _GLIBCXX_NODISCARD
      bool
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
      {
	auto __id = this_thread::get_id();
	_Can_lock __can_lock{this, __id};
	unique_lock<mutex> __lk(_M_mut);
	if (!_M_cv.wait_for(__lk, __rtime, __can_lock))
	  return false;
	if (_M_count == -1u)
	  return false;
	_M_owner = __id;
	++_M_count;
	return true;
      }

    template<typename _Clock, typename _Duration>
      _GLIBCXX_NODISCARD
      bool
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
      {
	auto __id = this_thread::get_id();
	_Can_lock __can_lock{this, __id};
	unique_lock<mutex> __lk(_M_mut);
	if (!_M_cv.wait_until(__lk, __atime, __can_lock))
	  return false;
	if (_M_count == -1u)
	  return false;
	_M_owner = __id;
	++_M_count;
	return true;
      }

    void
    unlock()
    {
      lock_guard<mutex> __lk(_M_mut);
      __glibcxx_assert( _M_owner == this_thread::get_id() );
      __glibcxx_assert( _M_count > 0 );
      if (--_M_count == 0)
	{
	  _M_owner = {};
	  _M_cv.notify_one();
	}
    }
  };

#endif
#endif // _GLIBCXX_HAS_GTHREADS

  /// @cond undocumented
  namespace __detail
  {
    // Lock the last lockable, after all previous ones are locked.
    template<typename _Lockable>
      inline int
      __try_lock_impl(_Lockable& __l)
      {
	if (unique_lock<_Lockable> __lock{__l, try_to_lock})
	  {
	    __lock.release();
	    return -1;
	  }
	else
	  return 0;
      }

    // Lock each lockable in turn.
    // Use iteration if all lockables are the same type, recursion otherwise.
    template<typename _L0, typename... _Lockables>
      inline int
      __try_lock_impl(_L0& __l0, _Lockables&... __lockables)
      {
#if __cplusplus >= 201703L
	if constexpr ((is_same_v<_L0, _Lockables> && ...))
	  {
	    constexpr int _Np = 1 + sizeof...(_Lockables);
	    unique_lock<_L0> __locks[_Np] = {
		{__l0, defer_lock}, {__lockables, defer_lock}...
	    };
	    for (int __i = 0; __i < _Np; ++__i)
	      {
		if (!__locks[__i].try_lock())
		  {
		    const int __failed = __i;
		    while (__i--)
		      __locks[__i].unlock();
		    return __failed;
		  }
	      }
	    for (auto& __l : __locks)
	      __l.release();
	    return -1;
	  }
	else
#endif
	if (unique_lock<_L0> __lock{__l0, try_to_lock})
	  {
	    int __idx = __detail::__try_lock_impl(__lockables...);
	    if (__idx == -1)
	      {
		__lock.release();
		return -1;
	      }
	    return __idx + 1;
	  }
	else
	  return 0;
      }

  } // namespace __detail
  /// @endcond

  /** @brief Generic try_lock.
   *  @param __l1 Meets Lockable requirements (try_lock() may throw).
   *  @param __l2 Meets Lockable requirements (try_lock() may throw).
   *  @param __l3 Meets Lockable requirements (try_lock() may throw).
   *  @return Returns -1 if all try_lock() calls return true. Otherwise returns
   *          a 0-based index corresponding to the argument that returned false.
   *  @post Either all arguments are locked, or none will be.
   *
   *  Sequentially calls try_lock() on each argument.
   */
  template<typename _L1, typename _L2, typename... _L3>
    _GLIBCXX_NODISCARD
    inline int
    try_lock(_L1& __l1, _L2& __l2, _L3&... __l3)
    {
      return __detail::__try_lock_impl(__l1, __l2, __l3...);
    }

  /// @cond undocumented
  namespace __detail
  {
    // This function can recurse up to N levels deep, for N = 1+sizeof...(L1).
    // On each recursion the lockables are rotated left one position,
    // e.g. depth 0: l0, l1, l2; depth 1: l1, l2, l0; depth 2: l2, l0, l1.
    // When a call to l_i.try_lock() fails it recurses/returns to depth=i
    // so that l_i is the first argument, and then blocks until l_i is locked.
    template<typename _L0, typename... _L1>
      void
      __lock_impl(int& __i, int __depth, _L0& __l0, _L1&... __l1)
      {
	while (__i >= __depth)
	  {
	    if (__i == __depth)
	      {
		int __failed = 1; // index that couldn't be locked
		{
		  unique_lock<_L0> __first(__l0);
		  __failed += __detail::__try_lock_impl(__l1...);
		  if (!__failed)
		    {
		      __i = -1; // finished
		      __first.release();
		      return;
		    }
		}
#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
		__gthread_yield();
#endif
		constexpr auto __n = 1 + sizeof...(_L1);
		__i = (__depth + __failed) % __n;
	      }
	    else // rotate left until l_i is first.
	      __detail::__lock_impl(__i, __depth + 1, __l1..., __l0);
	  }
      }

  } // namespace __detail
  /// @endcond

  /** @brief Generic lock.
   *  @param __l1 Meets Lockable requirements (try_lock() may throw).
   *  @param __l2 Meets Lockable requirements (try_lock() may throw).
   *  @param __l3 Meets Lockable requirements (try_lock() may throw).
   *  @throw An exception thrown by an argument's lock() or try_lock() member.
   *  @post All arguments are locked.
   *
   *  All arguments are locked via a sequence of calls to lock(), try_lock()
   *  and unlock().  If this function exits via an exception any locks that
   *  were obtained will be released.
   */
  template<typename _L1, typename _L2, typename... _L3>
    void
    lock(_L1& __l1, _L2& __l2, _L3&... __l3)
    {
#if __cplusplus >= 201703L
      if constexpr (is_same_v<_L1, _L2> && (is_same_v<_L1, _L3> && ...))
	{
	  constexpr int _Np = 2 + sizeof...(_L3);
	  unique_lock<_L1> __locks[] = {
	      {__l1, defer_lock}, {__l2, defer_lock}, {__l3, defer_lock}...
	  };
	  int __first = 0;
	  do {
	    __locks[__first].lock();
	    for (int __j = 1; __j < _Np; ++__j)
	      {
		const int __idx = (__first + __j) % _Np;
		if (!__locks[__idx].try_lock())
		  {
		    for (int __k = __j; __k != 0; --__k)
		      __locks[(__first + __k - 1) % _Np].unlock();
		    __first = __idx;
		    break;
		  }
	      }
	  } while (!__locks[__first].owns_lock());

	  for (auto& __l : __locks)
	    __l.release();
	}
      else
#endif
	{
	  int __i = 0;
	  __detail::__lock_impl(__i, 0, __l1, __l2, __l3...);
	}
    }

#ifdef __cpp_lib_scoped_lock // C++ >= 17
  /** @brief A scoped lock type for multiple lockable objects.
   *
   * A scoped_lock controls mutex ownership within a scope, releasing
   * ownership in the destructor.
   *
   * @headerfile mutex
   * @since C++17
   */
  template<typename... _MutexTypes>
    class scoped_lock
    {
    public:

      [[nodiscard]]
      explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...))
      { std::lock(__m...); }

      [[nodiscard]]
      explicit scoped_lock(adopt_lock_t, _MutexTypes&... __m) noexcept
      : _M_devices(std::tie(__m...))
      { } // calling thread owns mutex

      ~scoped_lock()
      { std::apply([](auto&... __m) { (__m.unlock(), ...); }, _M_devices); }

      scoped_lock(const scoped_lock&) = delete;
      scoped_lock& operator=(const scoped_lock&) = delete;

    private:
      tuple<_MutexTypes&...> _M_devices;
    };

  template<>
    class scoped_lock<>
    {
    public:
      explicit scoped_lock() = default;
      explicit scoped_lock(adopt_lock_t) noexcept { }
      ~scoped_lock() = default;

      scoped_lock(const scoped_lock&) = delete;
      scoped_lock& operator=(const scoped_lock&) = delete;
    };

  template<typename _Mutex>
    class scoped_lock<_Mutex>
    {
    public:
      using mutex_type = _Mutex;

      [[nodiscard]]
      explicit scoped_lock(mutex_type& __m) : _M_device(__m)
      { _M_device.lock(); }

      [[nodiscard]]
      explicit scoped_lock(adopt_lock_t, mutex_type& __m) noexcept
      : _M_device(__m)
      { } // calling thread owns mutex

      ~scoped_lock()
      { _M_device.unlock(); }

      scoped_lock(const scoped_lock&) = delete;
      scoped_lock& operator=(const scoped_lock&) = delete;

    private:
      mutex_type&  _M_device;
    };
#endif // __cpp_lib_scoped_lock

#ifdef _GLIBCXX_HAS_GTHREADS
  /// Flag type used by std::call_once
  struct once_flag
  {
    constexpr once_flag() noexcept = default;

    /// Deleted copy constructor
    once_flag(const once_flag&) = delete;
    /// Deleted assignment operator
    once_flag& operator=(const once_flag&) = delete;

  private:
    // For gthreads targets a pthread_once_t is used with pthread_once, but
    // for most targets this doesn't work correctly for exceptional executions.
    __gthread_once_t _M_once = __GTHREAD_ONCE_INIT;

    struct _Prepare_execution;

    template<typename _Callable, typename... _Args>
      friend void
      call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
  };

  /// @cond undocumented
# ifdef _GLIBCXX_HAVE_TLS
  // If TLS is available use thread-local state for the type-erased callable
  // that is being run by std::call_once in the current thread.
  extern __thread void* __once_callable;
  extern __thread void (*__once_call)();

  // RAII type to set up state for pthread_once call.
  struct once_flag::_Prepare_execution
  {
    template<typename _Callable>
      explicit
      _Prepare_execution(_Callable& __c)
      {
	// Store address in thread-local pointer:
	__once_callable = std::__addressof(__c);
	// Trampoline function to invoke the closure via thread-local pointer:
	__once_call = [] { (*static_cast<_Callable*>(__once_callable))(); };
      }

    ~_Prepare_execution()
    {
      // PR libstdc++/82481
      __once_callable = nullptr;
      __once_call = nullptr;
    }

    _Prepare_execution(const _Prepare_execution&) = delete;
    _Prepare_execution& operator=(const _Prepare_execution&) = delete;
  };

# else
  // Without TLS use a global std::mutex and store the callable in a
  // global std::function.
  extern function<void()> __once_functor;

  extern void
  __set_once_functor_lock_ptr(unique_lock<mutex>*);

  extern mutex&
  __get_once_mutex();

  // RAII type to set up state for pthread_once call.
  struct once_flag::_Prepare_execution
  {
    template<typename _Callable>
      explicit
      _Prepare_execution(_Callable& __c)
      {
	// Store the callable in the global std::function
	__once_functor = __c;
	__set_once_functor_lock_ptr(&_M_functor_lock);
      }

    ~_Prepare_execution()
    {
      if (_M_functor_lock)
	__set_once_functor_lock_ptr(nullptr);
    }

  private:
    // XXX This deadlocks if used recursively (PR 97949)
    unique_lock<mutex> _M_functor_lock{__get_once_mutex()};

    _Prepare_execution(const _Prepare_execution&) = delete;
    _Prepare_execution& operator=(const _Prepare_execution&) = delete;
  };
# endif
  /// @endcond

  // This function is passed to pthread_once by std::call_once.
  // It runs __once_call() or __once_functor().
  extern "C" void __once_proxy(void);

  /// Invoke a callable and synchronize with other calls using the same flag
  template<typename _Callable, typename... _Args>
    void
    call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
    {
      // Closure type that runs the function
      auto __callable = [&] {
	  std::__invoke(std::forward<_Callable>(__f),
			std::forward<_Args>(__args)...);
      };

      once_flag::_Prepare_execution __exec(__callable);

      // XXX pthread_once does not reset the flag if an exception is thrown.
      if (int __e = __gthread_once(&__once._M_once, &__once_proxy))
	__throw_system_error(__e);
    }

#else // _GLIBCXX_HAS_GTHREADS

  /// Flag type used by std::call_once
  struct once_flag
  {
    constexpr once_flag() noexcept = default;

    /// Deleted copy constructor
    once_flag(const once_flag&) = delete;
    /// Deleted assignment operator
    once_flag& operator=(const once_flag&) = delete;

  private:
    // There are two different std::once_flag interfaces, abstracting four
    // different implementations.
    // The single-threaded interface uses the _M_activate() and _M_finish(bool)
    // functions, which start and finish an active execution respectively.
    // See [thread.once.callonce] in C++11 for the definition of
    // active/passive/returning/exceptional executions.
    enum _Bits : int { _Init = 0, _Active = 1, _Done = 2 };

    int _M_once = _Bits::_Init;

    // Check to see if all executions will be passive now.
    bool
    _M_passive() const noexcept;

    // Attempts to begin an active execution.
    bool _M_activate();

    // Must be called to complete an active execution.
    // The argument is true if the active execution was a returning execution,
    // false if it was an exceptional execution.
    void _M_finish(bool __returning) noexcept;

    // RAII helper to call _M_finish.
    struct _Active_execution
    {
      explicit _Active_execution(once_flag& __flag) : _M_flag(__flag) { }

      ~_Active_execution() { _M_flag._M_finish(_M_returning); }

      _Active_execution(const _Active_execution&) = delete;
      _Active_execution& operator=(const _Active_execution&) = delete;

      once_flag& _M_flag;
      bool _M_returning = false;
    };

    template<typename _Callable, typename... _Args>
      friend void
      call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
  };

  // Inline definitions of std::once_flag members for single-threaded targets.

  inline bool
  once_flag::_M_passive() const noexcept
  { return _M_once == _Bits::_Done; }

  inline bool
  once_flag::_M_activate()
  {
    if (_M_once == _Bits::_Init) [[__likely__]]
      {
	_M_once = _Bits::_Active;
	return true;
      }
    else if (_M_passive()) // Caller should have checked this already.
      return false;
    else
      __throw_system_error(EDEADLK);
  }

  inline void
  once_flag::_M_finish(bool __returning) noexcept
  { _M_once = __returning ? _Bits::_Done : _Bits::_Init; }

  /// Invoke a callable and synchronize with other calls using the same flag
  template<typename _Callable, typename... _Args>
    inline void
    call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
    {
      if (__once._M_passive())
	return;
      else if (__once._M_activate())
	{
	  once_flag::_Active_execution __exec(__once);

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 2442. call_once() shouldn't DECAY_COPY()
	  std::__invoke(std::forward<_Callable>(__f),
			std::forward<_Args>(__args)...);

	  // __f(__args...) did not throw
	  __exec._M_returning = true;
	}
    }
#endif // _GLIBCXX_HAS_GTHREADS

  /// @} group mutexes
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // C++11

#endif // _GLIBCXX_MUTEX
