1    	// std::mutex implementation -*- C++ -*-
2    	
3    	// Copyright (C) 2003-2019 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file bits/std_mutex.h
26   	 *  This is an internal header file, included by other library headers.
27   	 *  Do not attempt to use it directly. @headername{mutex}
28   	 */
29   	
30   	#ifndef _GLIBCXX_MUTEX_H
31   	#define _GLIBCXX_MUTEX_H 1
32   	
33   	#pragma GCC system_header
34   	
35   	#if __cplusplus < 201103L
36   	# include <bits/c++0x_warning.h>
37   	#else
38   	
39   	#include <system_error>
40   	#include <bits/functexcept.h>
41   	#include <bits/gthr.h>
42   	
43   	namespace std _GLIBCXX_VISIBILITY(default)
44   	{
45   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
46   	
47   	  /**
48   	   * @defgroup mutexes Mutexes
49   	   * @ingroup concurrency
50   	   *
51   	   * Classes for mutex support.
52   	   * @{
53   	   */
54   	
55   	#ifdef _GLIBCXX_HAS_GTHREADS
56   	  // Common base class for std::mutex and std::timed_mutex
57   	  class __mutex_base
58   	  {
59   	  protected:
60   	    typedef __gthread_mutex_t			__native_type;
61   	
62   	#ifdef __GTHREAD_MUTEX_INIT
63   	    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
64   	
65   	    constexpr __mutex_base() noexcept = default;
66   	#else
67   	    __native_type  _M_mutex;
68   	
69   	    __mutex_base() noexcept
70   	    {
71   	      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
72   	      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
73   	    }
74   	
75   	    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
76   	#endif
77   	
78   	    __mutex_base(const __mutex_base&) = delete;
79   	    __mutex_base& operator=(const __mutex_base&) = delete;
80   	  };
81   	
82   	  /// The standard mutex type.
83   	  class mutex : private __mutex_base
84   	  {
85   	  public:
86   	    typedef __native_type* 			native_handle_type;
87   	
88   	#ifdef __GTHREAD_MUTEX_INIT
89   	    constexpr
90   	#endif
91   	    mutex() noexcept = default;
92   	    ~mutex() = default;
93   	
94   	    mutex(const mutex&) = delete;
95   	    mutex& operator=(const mutex&) = delete;
96   	
97   	    void
98   	    lock()
99   	    {
100  	      int __e = __gthread_mutex_lock(&_M_mutex);
101  	
102  	      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
103  	      if (__e)
104  		__throw_system_error(__e);
105  	    }
106  	
107  	    bool
108  	    try_lock() noexcept
109  	    {
110  	      // XXX EINVAL, EAGAIN, EBUSY
111  	      return !__gthread_mutex_trylock(&_M_mutex);
112  	    }
113  	
114  	    void
115  	    unlock()
116  	    {
117  	      // XXX EINVAL, EAGAIN, EPERM
118  	      __gthread_mutex_unlock(&_M_mutex);
119  	    }
120  	
121  	    native_handle_type
122  	    native_handle() noexcept
123  	    { return &_M_mutex; }
124  	  };
125  	
126  	#endif // _GLIBCXX_HAS_GTHREADS
127  	
128  	  /// Do not acquire ownership of the mutex.
129  	  struct defer_lock_t { explicit defer_lock_t() = default; };
130  	
131  	  /// Try to acquire ownership of the mutex without blocking.
132  	  struct try_to_lock_t { explicit try_to_lock_t() = default; };
133  	
134  	  /// Assume the calling thread has already obtained mutex ownership
135  	  /// and manage it.
136  	  struct adopt_lock_t { explicit adopt_lock_t() = default; };
137  	
138  	  /// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
139  	  _GLIBCXX17_INLINE constexpr defer_lock_t	defer_lock { };
140  	
141  	  /// Tag used to prevent a scoped lock from blocking if a mutex is locked.
142  	  _GLIBCXX17_INLINE constexpr try_to_lock_t	try_to_lock { };
143  	
144  	  /// Tag used to make a scoped lock take ownership of a locked mutex.
145  	  _GLIBCXX17_INLINE constexpr adopt_lock_t	adopt_lock { };
146  	
147  	  /** @brief A simple scoped lock type.
148  	   *
149  	   * A lock_guard controls mutex ownership within a scope, releasing
150  	   * ownership in the destructor.
151  	   */
152  	  template<typename _Mutex>
153  	    class lock_guard
154  	    {
155  	    public:
156  	      typedef _Mutex mutex_type;
157  	
158  	      explicit lock_guard(mutex_type& __m) : _M_device(__m)
(1) Event fun_call_w_exception: Called function throws an exception of type "_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEEE". [details]
159  	      { _M_device.lock(); }
160  	
161  	      lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
162  	      { } // calling thread owns mutex
163  	
164  	      ~lock_guard()
165  	      { _M_device.unlock(); }
166  	
167  	      lock_guard(const lock_guard&) = delete;
168  	      lock_guard& operator=(const lock_guard&) = delete;
169  	
170  	    private:
171  	      mutex_type&  _M_device;
172  	    };
173  	
174  	  // @} group mutexes
175  	_GLIBCXX_END_NAMESPACE_VERSION
176  	} // namespace
177  	#endif // C++11
178  	#endif // _GLIBCXX_MUTEX_H
179