Mercurial > hg > vamp-build-and-test
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/log/detail/locks.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,180 @@ +/* + * Copyright Andrey Semashev 2007 - 2013. + * 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; +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&) {} + +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) }; +}; + +//! 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) : m_Mutex(m) + { + m.lock(); + } + ~exclusive_lock_guard() + { + m_Mutex.unlock(); + } + +private: + exclusive_lock_guard(exclusive_lock_guard const&); + 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) : m_Mutex(m) + { + m.lock_shared(); + } + ~shared_lock_guard() + { + m_Mutex.unlock_shared(); + } + +private: + shared_lock_guard(shared_lock_guard const&); + 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) : + 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_