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)
9 * \author Andrey Semashev
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.
16 #ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
17 #define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
19 #include <boost/log/detail/config.hpp>
20 #include <boost/log/detail/header.hpp>
22 #ifdef BOOST_HAS_PRAGMA_ONCE
28 #ifndef BOOST_LOG_NO_THREADS
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.
35 class shared_lock_guard;
46 #endif // BOOST_LOG_NO_THREADS
48 BOOST_LOG_OPEN_NAMESPACE
50 //! An auxiliary pseudo-lock to express no locking requirements in logger features
51 template< typename MutexT >
56 * Constructs the pseudo-lock. The mutex is not affected during the construction.
58 explicit no_lock(MutexT&) {}
61 no_lock(no_lock const&);
62 no_lock& operator= (no_lock const&);
67 #ifndef BOOST_LOG_NO_THREADS
69 //! A trait to detect if the mutex supports exclusive locking
70 template< typename MutexT >
71 struct is_exclusively_lockable
73 typedef char true_type;
74 struct false_type { char t[2]; };
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*);
80 enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
83 //! A trait to detect if the mutex supports shared locking
84 template< typename MutexT >
85 struct is_shared_lockable
87 typedef char true_type;
88 struct false_type { char t[2]; };
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*);
94 enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
97 //! A scope guard that automatically unlocks the mutex on destruction
98 template< typename MutexT >
99 struct exclusive_auto_unlocker
101 explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m)
104 ~exclusive_auto_unlocker()
109 BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&))
110 BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&))
116 //! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
117 template< typename MutexT >
118 struct exclusive_lock_guard
120 explicit exclusive_lock_guard(MutexT& m) : m_Mutex(m)
124 ~exclusive_lock_guard()
129 BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&))
130 BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&))
136 //! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
137 template< typename MutexT >
138 struct shared_lock_guard
140 explicit shared_lock_guard(MutexT& m) : m_Mutex(m)
146 m_Mutex.unlock_shared();
149 BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&))
150 BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&))
156 //! A deadlock-safe lock type that exclusively locks two mutexes
157 template< typename MutexT1, typename MutexT2 >
158 class multiple_unique_lock2
161 multiple_unique_lock2(MutexT1& m1, MutexT2& m2) :
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))
178 ~multiple_unique_lock2()
189 #endif // BOOST_LOG_NO_THREADS
193 BOOST_LOG_CLOSE_NAMESPACE // namespace log
197 #include <boost/log/detail/footer.hpp>
199 #endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_