comparison DEPENDENCIES/generic/include/boost/log/detail/locks.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /*
2 * Copyright Andrey Semashev 2007 - 2013.
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
26 namespace 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.
32 template< typename >
33 class lock_guard;
34 template< typename >
35 class shared_lock;
36 template< typename >
37 class upgrade_lock;
38 template< typename >
39 class unique_lock;
40
41 template< typename >
42 struct is_mutex_type;
43
44 #endif // BOOST_LOG_NO_THREADS
45
46 BOOST_LOG_OPEN_NAMESPACE
47
48 //! An auxiliary pseudo-lock to express no locking requirements in logger features
49 template< typename MutexT >
50 class no_lock
51 {
52 public:
53 /*!
54 * Constructs the pseudo-lock. The mutex is not affected during the construction.
55 */
56 explicit no_lock(MutexT&) {}
57
58 private:
59 no_lock(no_lock const&);
60 no_lock& operator= (no_lock const&);
61 };
62
63 namespace aux {
64
65 #ifndef BOOST_LOG_NO_THREADS
66
67 //! A trait to detect if the mutex supports exclusive locking
68 template< typename MutexT >
69 struct is_exclusively_lockable
70 {
71 typedef char true_type;
72 struct false_type { char t[2]; };
73
74 template< typename T >
75 static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
76 static false_type check_lockable(void*);
77
78 enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
79 };
80
81 //! A trait to detect if the mutex supports shared locking
82 template< typename MutexT >
83 struct is_shared_lockable
84 {
85 typedef char true_type;
86 struct false_type { char t[2]; };
87
88 template< typename T >
89 static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
90 static false_type check_shared_lockable(void*);
91
92 enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
93 };
94
95 //! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
96 template< typename MutexT >
97 struct exclusive_lock_guard
98 {
99 explicit exclusive_lock_guard(MutexT& m) : m_Mutex(m)
100 {
101 m.lock();
102 }
103 ~exclusive_lock_guard()
104 {
105 m_Mutex.unlock();
106 }
107
108 private:
109 exclusive_lock_guard(exclusive_lock_guard const&);
110 exclusive_lock_guard& operator= (exclusive_lock_guard const&);
111
112 private:
113 MutexT& m_Mutex;
114 };
115
116 //! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
117 template< typename MutexT >
118 struct shared_lock_guard
119 {
120 explicit shared_lock_guard(MutexT& m) : m_Mutex(m)
121 {
122 m.lock_shared();
123 }
124 ~shared_lock_guard()
125 {
126 m_Mutex.unlock_shared();
127 }
128
129 private:
130 shared_lock_guard(shared_lock_guard const&);
131 shared_lock_guard& operator= (shared_lock_guard const&);
132
133 private:
134 MutexT& m_Mutex;
135 };
136
137 //! A deadlock-safe lock type that exclusively locks two mutexes
138 template< typename MutexT1, typename MutexT2 >
139 class multiple_unique_lock2
140 {
141 public:
142 multiple_unique_lock2(MutexT1& m1, MutexT2& m2) :
143 m_p1(&m1),
144 m_p2(&m2)
145 {
146 // Yes, it's not conforming, but it works
147 // and it doesn't require to #include <functional>
148 if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
149 {
150 m_p1->lock();
151 m_p2->lock();
152 }
153 else
154 {
155 m_p2->lock();
156 m_p1->lock();
157 }
158 }
159 ~multiple_unique_lock2()
160 {
161 m_p2->unlock();
162 m_p1->unlock();
163 }
164
165 private:
166 MutexT1* m_p1;
167 MutexT2* m_p2;
168 };
169
170 #endif // BOOST_LOG_NO_THREADS
171
172 } // namespace aux
173
174 BOOST_LOG_CLOSE_NAMESPACE // namespace log
175
176 } // namespace boost
177
178 #include <boost/log/detail/footer.hpp>
179
180 #endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_