123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /*
- * Copyright Andrey Semashev 2007 - 2015.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
- /*!
- * \file locks.hpp
- * \author Andrey Semashev
- * \date 30.05.2010
- *
- * \brief This header is the Boost.Log library implementation, see the library documentation
- * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
- */
- #ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
- #define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
- #include <boost/log/detail/config.hpp>
- #include <boost/log/detail/header.hpp>
- #ifdef BOOST_HAS_PRAGMA_ONCE
- #pragma once
- #endif
- namespace boost {
- #ifndef BOOST_LOG_NO_THREADS
- // Forward declaration of Boost.Thread locks. Specified here to avoid including Boost.Thread,
- // which would bring in many dependent headers, including a great deal of Boost.DateTime.
- template< typename >
- class lock_guard;
- template< typename >
- class shared_lock_guard;
- template< typename >
- class shared_lock;
- template< typename >
- class upgrade_lock;
- template< typename >
- class unique_lock;
- template< typename >
- struct is_mutex_type;
- #endif // BOOST_LOG_NO_THREADS
- BOOST_LOG_OPEN_NAMESPACE
- //! An auxiliary pseudo-lock to express no locking requirements in logger features
- template< typename MutexT >
- class no_lock
- {
- public:
- /*!
- * Constructs the pseudo-lock. The mutex is not affected during the construction.
- */
- explicit no_lock(MutexT&) BOOST_NOEXCEPT {}
- private:
- no_lock(no_lock const&);
- no_lock& operator= (no_lock const&);
- };
- namespace aux {
- #ifndef BOOST_LOG_NO_THREADS
- //! A trait to detect if the mutex supports exclusive locking
- template< typename MutexT >
- struct is_exclusively_lockable
- {
- typedef char true_type;
- struct false_type { char t[2]; };
- template< typename T >
- static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
- static false_type check_lockable(void*);
- enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
- };
- //! A trait to detect if the mutex supports shared locking
- template< typename MutexT >
- struct is_shared_lockable
- {
- typedef char true_type;
- struct false_type { char t[2]; };
- template< typename T >
- static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
- static false_type check_shared_lockable(void*);
- enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
- };
- //! A scope guard that automatically unlocks the mutex on destruction
- template< typename MutexT >
- struct exclusive_auto_unlocker
- {
- explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m)
- {
- }
- ~exclusive_auto_unlocker()
- {
- m_Mutex.unlock();
- }
- BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&))
- BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&))
- protected:
- MutexT& m_Mutex;
- };
- //! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
- template< typename MutexT >
- struct exclusive_lock_guard
- {
- explicit exclusive_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock())) : m_Mutex(m)
- {
- m.lock();
- }
- ~exclusive_lock_guard()
- {
- m_Mutex.unlock();
- }
- BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&))
- BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&))
- private:
- MutexT& m_Mutex;
- };
- //! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
- template< typename MutexT >
- struct shared_lock_guard
- {
- explicit shared_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock_shared())) : m_Mutex(m)
- {
- m.lock_shared();
- }
- ~shared_lock_guard()
- {
- m_Mutex.unlock_shared();
- }
- BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&))
- BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&))
- private:
- MutexT& m_Mutex;
- };
- //! A deadlock-safe lock type that exclusively locks two mutexes
- template< typename MutexT1, typename MutexT2 >
- class multiple_unique_lock2
- {
- public:
- multiple_unique_lock2(MutexT1& m1, MutexT2& m2) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.lock()) && BOOST_NOEXCEPT_EXPR(m2.lock())) :
- m_p1(&m1),
- m_p2(&m2)
- {
- // Yes, it's not conforming, but it works
- // and it doesn't require to #include <functional>
- if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
- {
- m_p1->lock();
- m_p2->lock();
- }
- else
- {
- m_p2->lock();
- m_p1->lock();
- }
- }
- ~multiple_unique_lock2()
- {
- m_p2->unlock();
- m_p1->unlock();
- }
- private:
- MutexT1* m_p1;
- MutexT2* m_p2;
- };
- #endif // BOOST_LOG_NO_THREADS
- } // namespace aux
- BOOST_LOG_CLOSE_NAMESPACE // namespace log
- } // namespace boost
- #include <boost/log/detail/footer.hpp>
- #endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
|