// Support for concurrent programing -*- C++ -*-

// Copyright (C) 2003-2026 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 ext/concurrence.h
 *  This file is a GNU extension to the Standard C++ Library.
 */

#ifndef _CONCURRENCE_H
#define _CONCURRENCE_H 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <exception>
#include <bits/gthr.h>
#include <bits/exception_defines.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++11-extensions"

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // Available locking policies:
  // _S_single    single-threaded code that doesn't need to be locked.
  // _S_mutex     multi-threaded code that requires additional support
  //              from gthr.h or abstraction layers in concurrence.h.
  // _S_atomic    multi-threaded code using atomic operations.
  enum _Lock_policy { _S_single, _S_mutex, _S_atomic };

  // Compile time constant that indicates preferred locking policy in
  // the current configuration.
  _GLIBCXX17_INLINE const _Lock_policy __default_lock_policy =
#ifndef __GTHREADS
  _S_single;
#elif defined _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY
  _S_atomic;
#else
  _S_mutex;
#endif

  // NB: As this is used in libsupc++, need to only depend on
  // exception. No stdexception classes, no use of std::string.
  class __concurrence_lock_error : public std::exception
  {
  public:
    virtual char const*
    what() const throw()
    { return "__gnu_cxx::__concurrence_lock_error"; }
  };

  class __concurrence_unlock_error : public std::exception
  {
  public:
    virtual char const*
    what() const throw()
    { return "__gnu_cxx::__concurrence_unlock_error"; }
  };

  class __concurrence_broadcast_error : public std::exception
  {
  public:
    virtual char const*
    what() const throw()
    { return "__gnu_cxx::__concurrence_broadcast_error"; }
  };

  class __concurrence_wait_error : public std::exception
  {
  public:
    virtual char const*
    what() const throw()
    { return "__gnu_cxx::__concurrence_wait_error"; }
  };

  // Substitute for concurrence_error object in the case of -fno-exceptions.
  inline void
  __throw_concurrence_lock_error()
  { _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); }

  inline void
  __throw_concurrence_unlock_error()
  { _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); }

#ifdef __GTHREAD_HAS_COND
  inline void
  __throw_concurrence_broadcast_error()
  { _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); }

  inline void
  __throw_concurrence_wait_error()
  { _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); }
#endif

  class __mutex
  {
  private:
#if __GTHREADS && defined __GTHREAD_MUTEX_INIT
    __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT;
#else
    __gthread_mutex_t _M_mutex;
#endif

    __mutex(const __mutex&);
    __mutex& operator=(const __mutex&);

  public:
    __mutex()
    {
#if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
      if (__gthread_active_p())
	__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
    }

#if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
    ~__mutex()
    {
      if (__gthread_active_p())
	__gthread_mutex_destroy(&_M_mutex);
    }
#endif

    void lock()
    {
#if __GTHREADS
      if (__gthread_active_p())
	{
	  if (__gthread_mutex_lock(&_M_mutex) != 0)
	    __throw_concurrence_lock_error();
	}
#endif
    }

    void unlock()
    {
#if __GTHREADS
      if (__gthread_active_p())
	{
	  if (__gthread_mutex_unlock(&_M_mutex) != 0)
	    __throw_concurrence_unlock_error();
	}
#endif
    }

    __gthread_mutex_t* gthread_mutex(void)
      { return &_M_mutex; }
  };

  class __recursive_mutex
  {
  private:
#if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT
    __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
#else
    __gthread_recursive_mutex_t _M_mutex;
#endif

    __recursive_mutex(const __recursive_mutex&);
    __recursive_mutex& operator=(const __recursive_mutex&);

  public:
    __recursive_mutex()
    {
#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
      if (__gthread_active_p())
	__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
    }

#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
    ~__recursive_mutex()
    {
      if (__gthread_active_p())
	__gthread_recursive_mutex_destroy(&_M_mutex);
    }
#endif

    void lock()
    {
#if __GTHREADS
      if (__gthread_active_p())
	{
	  if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
	    __throw_concurrence_lock_error();
	}
#endif
    }

    void unlock()
    {
#if __GTHREADS
      if (__gthread_active_p())
	{
	  if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
	    __throw_concurrence_unlock_error();
	}
#endif
    }

    __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
    { return &_M_mutex; }
  };

  /// Scoped lock idiom.
  // Acquire the mutex here with a constructor call, then release with
  // the destructor call in accordance with RAII style.
  class __scoped_lock
  {
  public:
    typedef __mutex __mutex_type;

  private:
    __mutex_type& _M_device;

    __scoped_lock(const __scoped_lock&);
    __scoped_lock& operator=(const __scoped_lock&);

  public:
    explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
    { _M_device.lock(); }

    ~__scoped_lock() throw()
    { _M_device.unlock(); }
  };

#ifdef __GTHREAD_HAS_COND
  class __cond
  {
  private:
#if __GTHREADS && defined __GTHREAD_COND_INIT
    __gthread_cond_t _M_cond = __GTHREAD_COND_INIT;
#else
    __gthread_cond_t _M_cond;
#endif

    __cond(const __cond&);
    __cond& operator=(const __cond&);

  public:
    __cond()
    {
#if __GTHREADS && ! defined __GTHREAD_COND_INIT
      if (__gthread_active_p())
	__GTHREAD_COND_INIT_FUNCTION(&_M_cond);
#endif
    }

#if __GTHREADS && ! defined __GTHREAD_COND_INIT
    ~__cond()
    {
      if (__gthread_active_p())
	__gthread_cond_destroy(&_M_cond);
    }
#endif

    void broadcast()
    {
#if __GTHREADS
      if (__gthread_active_p())
	{
	  if (__gthread_cond_broadcast(&_M_cond) != 0)
	    __throw_concurrence_broadcast_error();
	}
#endif
    }

    void wait(__mutex *__mx)
    {
#if __GTHREADS
      {
	  if (__gthread_cond_wait(&_M_cond, __mx->gthread_mutex()) != 0)
	    __throw_concurrence_wait_error();
      }
#endif
    }

    void wait_recursive(__recursive_mutex *__mx)
    {
#if __GTHREADS
      {
	  if (__gthread_cond_wait_recursive(&_M_cond,
					    __mx->gthread_recursive_mutex())
	      != 0)
	    __throw_concurrence_wait_error();
      }
#endif
    }
  };
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#pragma GCC diagnostic pop

#endif
