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_NAMED_SEMAPHORE_HPP Chris@16: #define BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP 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: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES) Chris@16: #include 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: #else Chris@16: #include Chris@16: #endif Chris@16: Chris@16: //!\file Chris@16: //!Describes a named semaphore class for inter-process synchronization Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: Chris@16: //!A semaphore with a global name, so it can be found from different Chris@16: //!processes. Allows several resource sharing patterns and efficient Chris@16: //!acknowledgment mechanisms. Chris@16: class named_semaphore Chris@16: { Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: Chris@16: //Non-copyable Chris@16: named_semaphore(); Chris@16: named_semaphore(const named_semaphore &); Chris@16: named_semaphore &operator=(const named_semaphore &); Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Creates a global semaphore with a name, and an initial count. Chris@16: //!If the semaphore can't be created throws interprocess_exception Chris@16: named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions()); Chris@16: Chris@16: //!Opens or creates a global semaphore with a name, and an initial count. Chris@16: //!If the semaphore is created, this call is equivalent to Chris@16: //!named_semaphore(create_only_t, ...) Chris@16: //!If the semaphore is already created, this call is equivalent to Chris@16: //!named_semaphore(open_only_t, ... ) Chris@16: //!and initialCount is ignored. Chris@16: named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions()); Chris@16: Chris@16: //!Opens a global semaphore with a name if that semaphore is previously. Chris@16: //!created. If it is not previously created this function throws Chris@16: //!interprocess_exception. Chris@16: named_semaphore(open_only_t, const char *name); Chris@16: Chris@16: //!Destroys *this and indicates that the calling process is finished using Chris@16: //!the resource. The destructor function will deallocate Chris@16: //!any system resources allocated by the system for use by this process for Chris@16: //!this resource. The resource can still be opened again calling Chris@16: //!the open constructor overload. To erase the resource from the system Chris@16: //!use remove(). Chris@16: ~named_semaphore(); Chris@16: Chris@16: //!Increments the semaphore count. If there are processes/threads blocked waiting Chris@16: //!for the 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 semaphore. If the 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 semaphore if the 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 semaphore if the semaphore's value is greater Chris@16: //!than zero and returns true. Otherwise, waits for the semaphore Chris@16: //!to the posted or the timeout expires. If the timeout expires, the Chris@16: //!function returns false. If the 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: //!Erases a named semaphore from the system. Chris@16: //!Returns false on error. Never throws. Chris@16: static bool remove(const char *name); Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: friend class ipcdetail::interprocess_tester; Chris@16: void dont_close_on_destruction(); Chris@16: Chris@16: #if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES) Chris@16: typedef ipcdetail::posix_named_semaphore impl_t; Chris@16: #elif defined(BOOST_INTERPROCESS_USE_WINDOWS) Chris@16: #undef BOOST_INTERPROCESS_USE_WINDOWS Chris@16: typedef ipcdetail::windows_named_semaphore impl_t; Chris@16: #else Chris@16: typedef ipcdetail::shm_named_semaphore impl_t; Chris@16: #endif Chris@16: impl_t m_sem; Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: }; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: Chris@16: inline named_semaphore::named_semaphore Chris@16: (create_only_t, const char *name, unsigned int initialCount, const permissions &perm) Chris@16: : m_sem(create_only, name, initialCount, perm) Chris@16: {} Chris@16: Chris@16: inline named_semaphore::named_semaphore Chris@16: (open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm) Chris@16: : m_sem(open_or_create, name, initialCount, perm) Chris@16: {} Chris@16: Chris@16: inline named_semaphore::named_semaphore(open_only_t, const char *name) Chris@16: : m_sem(open_only, name) Chris@16: {} Chris@16: Chris@16: inline named_semaphore::~named_semaphore() Chris@16: {} Chris@16: Chris@16: inline void named_semaphore::dont_close_on_destruction() Chris@16: { ipcdetail::interprocess_tester::dont_close_on_destruction(m_sem); } Chris@16: Chris@16: inline void named_semaphore::wait() Chris@16: { m_sem.wait(); } Chris@16: Chris@16: inline void named_semaphore::post() Chris@16: { m_sem.post(); } Chris@16: Chris@16: inline bool named_semaphore::try_wait() Chris@16: { return m_sem.try_wait(); } Chris@16: Chris@16: inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) Chris@101: { return m_sem.timed_wait(abs_time); } Chris@16: Chris@16: inline bool named_semaphore::remove(const char *name) Chris@16: { return impl_t::remove(name); } Chris@16: Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: } //namespace interprocess { Chris@16: } //namespace boost { Chris@16: Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP