]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/log/detail/locks.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / log / detail / locks.hpp
CommitLineData
7c673cae
FG
1/*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7/*!
8 * \file locks.hpp
9 * \author Andrey Semashev
10 * \date 30.05.2010
11 *
12 * \brief This header is the Boost.Log library implementation, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 */
15
16#ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
17#define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
18
19#include <boost/log/detail/config.hpp>
20#include <boost/log/detail/header.hpp>
21
22#ifdef BOOST_HAS_PRAGMA_ONCE
23#pragma once
24#endif
25
26namespace boost {
27
28#ifndef BOOST_LOG_NO_THREADS
29
30// Forward declaration of Boost.Thread locks. Specified here to avoid including Boost.Thread,
31// which would bring in many dependent headers, including a great deal of Boost.DateTime.
32template< typename >
33class lock_guard;
34template< typename >
35class shared_lock_guard;
36template< typename >
37class shared_lock;
38template< typename >
39class upgrade_lock;
40template< typename >
41class unique_lock;
42
43template< typename >
44struct is_mutex_type;
45
46#endif // BOOST_LOG_NO_THREADS
47
48BOOST_LOG_OPEN_NAMESPACE
49
50//! An auxiliary pseudo-lock to express no locking requirements in logger features
51template< typename MutexT >
52class no_lock
53{
54public:
55 /*!
56 * Constructs the pseudo-lock. The mutex is not affected during the construction.
57 */
20effc67 58 explicit no_lock(MutexT&) BOOST_NOEXCEPT {}
7c673cae
FG
59
60private:
61 no_lock(no_lock const&);
62 no_lock& operator= (no_lock const&);
63};
64
65namespace aux {
66
67#ifndef BOOST_LOG_NO_THREADS
68
69//! A trait to detect if the mutex supports exclusive locking
70template< typename MutexT >
71struct is_exclusively_lockable
72{
73 typedef char true_type;
74 struct false_type { char t[2]; };
75
76 template< typename T >
77 static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
78 static false_type check_lockable(void*);
79
80 enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
81};
82
83//! A trait to detect if the mutex supports shared locking
84template< typename MutexT >
85struct is_shared_lockable
86{
87 typedef char true_type;
88 struct false_type { char t[2]; };
89
90 template< typename T >
91 static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
92 static false_type check_shared_lockable(void*);
93
94 enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
95};
96
97//! A scope guard that automatically unlocks the mutex on destruction
98template< typename MutexT >
99struct exclusive_auto_unlocker
100{
101 explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m)
102 {
103 }
104 ~exclusive_auto_unlocker()
105 {
106 m_Mutex.unlock();
107 }
108
109 BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&))
110 BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&))
111
112protected:
113 MutexT& m_Mutex;
114};
115
116//! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
117template< typename MutexT >
118struct exclusive_lock_guard
119{
20effc67 120 explicit exclusive_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock())) : m_Mutex(m)
7c673cae
FG
121 {
122 m.lock();
123 }
124 ~exclusive_lock_guard()
125 {
126 m_Mutex.unlock();
127 }
128
129 BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&))
130 BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&))
131
132private:
133 MutexT& m_Mutex;
134};
135
136//! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
137template< typename MutexT >
138struct shared_lock_guard
139{
20effc67 140 explicit shared_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock_shared())) : m_Mutex(m)
7c673cae
FG
141 {
142 m.lock_shared();
143 }
144 ~shared_lock_guard()
145 {
146 m_Mutex.unlock_shared();
147 }
148
149 BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&))
150 BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&))
151
152private:
153 MutexT& m_Mutex;
154};
155
156//! A deadlock-safe lock type that exclusively locks two mutexes
157template< typename MutexT1, typename MutexT2 >
158class multiple_unique_lock2
159{
160public:
20effc67 161 multiple_unique_lock2(MutexT1& m1, MutexT2& m2) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.lock()) && BOOST_NOEXCEPT_EXPR(m2.lock())) :
7c673cae
FG
162 m_p1(&m1),
163 m_p2(&m2)
164 {
165 // Yes, it's not conforming, but it works
166 // and it doesn't require to #include <functional>
167 if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
168 {
169 m_p1->lock();
170 m_p2->lock();
171 }
172 else
173 {
174 m_p2->lock();
175 m_p1->lock();
176 }
177 }
178 ~multiple_unique_lock2()
179 {
180 m_p2->unlock();
181 m_p1->unlock();
182 }
183
184private:
185 MutexT1* m_p1;
186 MutexT2* m_p2;
187};
188
189#endif // BOOST_LOG_NO_THREADS
190
191} // namespace aux
192
193BOOST_LOG_CLOSE_NAMESPACE // namespace log
194
195} // namespace boost
196
197#include <boost/log/detail/footer.hpp>
198
199#endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_