123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2005-2012. 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)
- //
- // See http://www.boost.org/libs/interprocess for documentation.
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // Parts of the pthread code come from Boost Threads code.
- //
- //////////////////////////////////////////////////////////////////////////////
- #ifndef BOOST_INTERPROCESS_MUTEX_HPP
- #define BOOST_INTERPROCESS_MUTEX_HPP
- /// @cond
- #if (defined _MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif
- #include <boost/interprocess/detail/config_begin.hpp>
- #include <boost/interprocess/exceptions.hpp>
- #include <boost/interprocess/detail/workaround.hpp>
- #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
- #include <boost/assert.hpp>
- #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
- #include <boost/interprocess/sync/posix/mutex.hpp>
- #define BOOST_INTERPROCESS_USE_POSIX
- //Experimental...
- #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
- #include <boost/interprocess/sync/windows/mutex.hpp>
- #define BOOST_INTERPROCESS_USE_WINDOWS
- #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- #include <boost/interprocess/sync/spin/mutex.hpp>
- #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
- namespace boost {
- namespace interprocess {
- namespace ipcdetail{
- namespace robust_emulation_helpers {
- template<class T>
- class mutex_traits;
- }}}}
- #endif
- /// @endcond
- //!\file
- //!Describes a mutex class that can be placed in memory shared by
- //!several processes.
- namespace boost {
- namespace interprocess {
- class interprocess_condition;
- //!Wraps a interprocess_mutex that can be placed in shared memory and can be
- //!shared between processes. Allows timed lock tries
- class interprocess_mutex
- {
- /// @cond
- //Non-copyable
- interprocess_mutex(const interprocess_mutex &);
- interprocess_mutex &operator=(const interprocess_mutex &);
- friend class interprocess_condition;
- public:
- #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
- typedef ipcdetail::spin_mutex internal_mutex_type;
- private:
- friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
- void take_ownership(){ m_mutex.take_ownership(); }
- public:
- #elif defined(BOOST_INTERPROCESS_USE_POSIX)
- #undef BOOST_INTERPROCESS_USE_POSIX
- typedef ipcdetail::posix_mutex internal_mutex_type;
- #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
- #undef BOOST_INTERPROCESS_USE_WINDOWS
- typedef ipcdetail::windows_mutex internal_mutex_type;
- #else
- #error "Unknown platform for interprocess_mutex"
- #endif
- /// @endcond
- public:
- //!Constructor.
- //!Throws interprocess_exception on error.
- interprocess_mutex();
- //!Destructor. If any process uses the mutex after the destructor is called
- //!the result is undefined. Does not throw.
- ~interprocess_mutex();
- //!Effects: The calling thread tries to obtain ownership of the mutex, and
- //! if another thread has ownership of the mutex, it waits until it can
- //! obtain the ownership. If a thread takes ownership of the mutex the
- //! mutex must be unlocked by the same mutex.
- //!Throws: interprocess_exception on error.
- void lock();
- //!Effects: The calling thread tries to obtain ownership of the mutex, and
- //! if another thread has ownership of the mutex returns immediately.
- //!Returns: If the thread acquires ownership of the mutex, returns true, if
- //! the another thread has ownership of the mutex, returns false.
- //!Throws: interprocess_exception on error.
- bool try_lock();
- //!Effects: The calling thread will try to obtain exclusive ownership of the
- //! mutex if it can do so in until the specified time is reached. If the
- //! mutex supports recursive locking, the mutex must be unlocked the same
- //! number of times it is locked.
- //!Returns: If the thread acquires ownership of the mutex, returns true, if
- //! the timeout expires returns false.
- //!Throws: interprocess_exception on error.
- bool timed_lock(const boost::posix_time::ptime &abs_time);
- //!Effects: The calling thread releases the exclusive ownership of the mutex.
- //!Throws: interprocess_exception on error.
- void unlock();
- /// @cond
- internal_mutex_type &internal_mutex()
- { return m_mutex; }
- const internal_mutex_type &internal_mutex() const
- { return m_mutex; }
- private:
- internal_mutex_type m_mutex;
- /// @endcond
- };
- } //namespace interprocess {
- } //namespace boost {
- namespace boost {
- namespace interprocess {
- inline interprocess_mutex::interprocess_mutex(){}
- inline interprocess_mutex::~interprocess_mutex(){}
- inline void interprocess_mutex::lock()
- {
- #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
- boost::posix_time::ptime wait_time
- = boost::posix_time::microsec_clock::universal_time()
- + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
- if (!m_mutex.timed_lock(wait_time))
- {
- throw interprocess_exception(timeout_when_locking_error
- , "Interprocess mutex timeout when locking. Possible deadlock: "
- "owner died without unlocking?");
- }
- #else
- m_mutex.lock();
- #endif
- }
- inline bool interprocess_mutex::try_lock()
- { return m_mutex.try_lock(); }
- inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
- { return m_mutex.timed_lock(abs_time); }
- inline void interprocess_mutex::unlock()
- { m_mutex.unlock(); }
- } //namespace interprocess {
- } //namespace boost {
- #include <boost/interprocess/detail/config_end.hpp>
- #endif //BOOST_INTERPROCESS_MUTEX_HPP
|