1 // std::unique_lock implementation -*- C++ -*-
3 // Copyright (C) 2008-2019 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file bits/unique_lock.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{mutex}
30 #ifndef _GLIBCXX_UNIQUE_LOCK_H
31 #define _GLIBCXX_UNIQUE_LOCK_H 1
33 #pragma GCC system_header
35 #if __cplusplus < 201103L
36 # include <bits/c++0x_warning.h>
40 #include <bits/move.h> // for std::swap
42 namespace std
_GLIBCXX_VISIBILITY(default)
44 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 /** @brief A movable scoped lock type.
48 * A unique_lock controls mutex ownership within a scope. Ownership of the
49 * mutex can be delayed until after construction and can be transferred
50 * to another unique_lock by move construction or move assignment. If a
51 * mutex lock is owned when the destructor runs ownership will be released.
55 template<typename _Mutex
>
59 typedef _Mutex mutex_type
;
61 unique_lock() noexcept
62 : _M_device(0), _M_owns(false)
65 explicit unique_lock(mutex_type
& __m
)
66 : _M_device(std::__addressof(__m
)), _M_owns(false)
72 unique_lock(mutex_type
& __m
, defer_lock_t
) noexcept
73 : _M_device(std::__addressof(__m
)), _M_owns(false)
76 unique_lock(mutex_type
& __m
, try_to_lock_t
)
77 : _M_device(std::__addressof(__m
)), _M_owns(_M_device
->try_lock())
80 unique_lock(mutex_type
& __m
, adopt_lock_t
) noexcept
81 : _M_device(std::__addressof(__m
)), _M_owns(true)
83 // XXX calling thread owns mutex
86 template<typename _Clock
, typename _Duration
>
87 unique_lock(mutex_type
& __m
,
88 const chrono::time_point
<_Clock
, _Duration
>& __atime
)
89 : _M_device(std::__addressof(__m
)),
90 _M_owns(_M_device
->try_lock_until(__atime
))
93 template<typename _Rep
, typename _Period
>
94 unique_lock(mutex_type
& __m
,
95 const chrono::duration
<_Rep
, _Period
>& __rtime
)
96 : _M_device(std::__addressof(__m
)),
97 _M_owns(_M_device
->try_lock_for(__rtime
))
106 unique_lock(const unique_lock
&) = delete;
107 unique_lock
& operator=(const unique_lock
&) = delete;
109 unique_lock(unique_lock
&& __u
) noexcept
110 : _M_device(__u
._M_device
), _M_owns(__u
._M_owns
)
116 unique_lock
& operator=(unique_lock
&& __u
) noexcept
121 unique_lock(std::move(__u
)).swap(*this);
133 __throw_system_error(int(errc::operation_not_permitted
));
135 __throw_system_error(int(errc::resource_deadlock_would_occur
));
147 __throw_system_error(int(errc::operation_not_permitted
));
149 __throw_system_error(int(errc::resource_deadlock_would_occur
));
152 _M_owns
= _M_device
->try_lock();
157 template<typename _Clock
, typename _Duration
>
159 try_lock_until(const chrono::time_point
<_Clock
, _Duration
>& __atime
)
162 __throw_system_error(int(errc::operation_not_permitted
));
164 __throw_system_error(int(errc::resource_deadlock_would_occur
));
167 _M_owns
= _M_device
->try_lock_until(__atime
);
172 template<typename _Rep
, typename _Period
>
174 try_lock_for(const chrono::duration
<_Rep
, _Period
>& __rtime
)
177 __throw_system_error(int(errc::operation_not_permitted
));
179 __throw_system_error(int(errc::resource_deadlock_would_occur
));
182 _M_owns
= _M_device
->try_lock_for(__rtime
);
191 __throw_system_error(int(errc::operation_not_permitted
));
200 swap(unique_lock
& __u
) noexcept
202 std::swap(_M_device
, __u
._M_device
);
203 std::swap(_M_owns
, __u
._M_owns
);
209 mutex_type
* __ret
= _M_device
;
216 owns_lock() const noexcept
219 explicit operator bool() const noexcept
220 { return owns_lock(); }
223 mutex() const noexcept
224 { return _M_device
; }
227 mutex_type
* _M_device
;
231 /// Swap overload for unique_lock objects.
232 /// @relates unique_lock
233 template<typename _Mutex
>
235 swap(unique_lock
<_Mutex
>& __x
, unique_lock
<_Mutex
>& __y
) noexcept
238 _GLIBCXX_END_NAMESPACE_VERSION
242 #endif // _GLIBCXX_UNIQUE_LOCK_H