Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP Chris@16: #define BOOST_INTERPROCESS_SEMAPHORE_HPP Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \ Chris@101: (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES)) Chris@16: #include Chris@16: #define BOOST_INTERPROCESS_USE_POSIX Chris@16: //Experimental... Chris@16: #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS) Chris@16: #include Chris@16: #define BOOST_INTERPROCESS_USE_WINDOWS Chris@16: #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: #include Chris@16: #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION Chris@16: #endif Chris@16: Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: //!\file Chris@16: //!Describes a interprocess_semaphore class for inter-process synchronization Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: Chris@16: //!Wraps a interprocess_semaphore that can be placed in shared memory and can be Chris@16: //!shared between processes. Allows timed lock tries Chris@16: class interprocess_semaphore Chris@16: { Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: //Non-copyable Chris@16: interprocess_semaphore(const interprocess_semaphore &); Chris@16: interprocess_semaphore &operator=(const interprocess_semaphore &); Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: public: Chris@16: //!Creates a interprocess_semaphore with the given initial count. Chris@16: //!interprocess_exception if there is an error.*/ Chris@16: interprocess_semaphore(unsigned int initialCount); Chris@16: Chris@16: //!Destroys the interprocess_semaphore. Chris@16: //!Does not throw Chris@16: ~interprocess_semaphore(); Chris@16: Chris@16: //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting Chris@16: //!for the interprocess_semaphore, then one of these processes will return successfully from Chris@16: //!its wait function. If there is an error an interprocess_exception exception is thrown. Chris@16: void post(); Chris@16: Chris@16: //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero, Chris@16: //!then the calling process/thread blocks until it can decrement the counter. Chris@16: //!If there is an error an interprocess_exception exception is thrown. Chris@16: void wait(); Chris@16: Chris@16: //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero Chris@16: //!and returns true. If the value is not greater than zero returns false. Chris@16: //!If there is an error an interprocess_exception exception is thrown. Chris@16: bool try_wait(); Chris@16: Chris@16: //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater Chris@16: //!than zero and returns true. Otherwise, waits for the interprocess_semaphore Chris@16: //!to the posted or the timeout expires. If the timeout expires, the Chris@16: //!function returns false. If the interprocess_semaphore is posted the function Chris@16: //!returns true. If there is an error throws sem_exception Chris@16: bool timed_wait(const boost::posix_time::ptime &abs_time); Chris@16: Chris@16: //!Returns the interprocess_semaphore count Chris@16: // int get_count() const; Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) Chris@16: #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION Chris@16: ipcdetail::spin_semaphore m_sem; Chris@16: #elif defined(BOOST_INTERPROCESS_USE_WINDOWS) Chris@16: #undef BOOST_INTERPROCESS_USE_WINDOWS Chris@16: ipcdetail::windows_semaphore m_sem; Chris@16: #else Chris@16: #undef BOOST_INTERPROCESS_USE_POSIX Chris@16: ipcdetail::posix_semaphore m_sem; Chris@16: #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: }; Chris@16: Chris@16: } //namespace interprocess { Chris@16: } //namespace boost { Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: Chris@16: inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount) Chris@16: : m_sem(initialCount) Chris@16: {} Chris@16: Chris@16: inline interprocess_semaphore::~interprocess_semaphore(){} Chris@16: Chris@16: inline void interprocess_semaphore::wait() Chris@16: { Chris@16: #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING Chris@16: boost::posix_time::ptime wait_time Chris@16: = boost::posix_time::microsec_clock::universal_time() Chris@16: + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS); Chris@16: if (!m_sem.timed_wait(wait_time)) Chris@16: { Chris@16: throw interprocess_exception(timeout_when_waiting_error, "Interprocess semaphore timeout when waiting. Possible deadlock: owner died without posting?"); Chris@16: } Chris@16: #else Chris@16: m_sem.wait(); Chris@16: #endif Chris@16: } Chris@16: inline bool interprocess_semaphore::try_wait() Chris@16: { return m_sem.try_wait(); } Chris@16: Chris@16: inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) Chris@16: { return m_sem.timed_wait(abs_time); } Chris@16: Chris@16: inline void interprocess_semaphore::post() Chris@16: { m_sem.post(); } Chris@16: Chris@16: } //namespace interprocess { Chris@16: } //namespace boost { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP