summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync/interprocess_semaphore.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync/interprocess_semaphore.hpp')
-rw-r--r--boost/interprocess/sync/interprocess_semaphore.hpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/boost/interprocess/sync/interprocess_semaphore.hpp b/boost/interprocess/sync/interprocess_semaphore.hpp
new file mode 100644
index 0000000..4ffcdcf
--- /dev/null
+++ b/boost/interprocess/sync/interprocess_semaphore.hpp
@@ -0,0 +1,145 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP
+#define BOOST_INTERPROCESS_SEMAPHORE_HPP
+
+/// @cond
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
+ (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES))
+ #include <boost/interprocess/sync/posix/semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_POSIX
+//Experimental...
+//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+// #include <boost/interprocess/sync/windows/semaphore.hpp>
+// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #include <boost/interprocess/sync/spin/semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
+#endif
+
+/// @endcond
+
+//!\file
+//!Describes a interprocess_semaphore class for inter-process synchronization
+
+namespace boost {
+namespace interprocess {
+
+//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
+//!shared between processes. Allows timed lock tries
+class interprocess_semaphore
+{
+ /// @cond
+ //Non-copyable
+ interprocess_semaphore(const interprocess_semaphore &);
+ interprocess_semaphore &operator=(const interprocess_semaphore &);
+ /// @endcond
+ public:
+ //!Creates a interprocess_semaphore with the given initial count.
+ //!interprocess_exception if there is an error.*/
+ interprocess_semaphore(unsigned int initialCount);
+
+ //!Destroys the interprocess_semaphore.
+ //!Does not throw
+ ~interprocess_semaphore();
+
+ //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
+ //!for the interprocess_semaphore, then one of these processes will return successfully from
+ //!its wait function. If there is an error an interprocess_exception exception is thrown.
+ void post();
+
+ //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
+ //!then the calling process/thread blocks until it can decrement the counter.
+ //!If there is an error an interprocess_exception exception is thrown.
+ void wait();
+
+ //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
+ //!and returns true. If the value is not greater than zero returns false.
+ //!If there is an error an interprocess_exception exception is thrown.
+ bool try_wait();
+
+ //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
+ //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
+ //!to the posted or the timeout expires. If the timeout expires, the
+ //!function returns false. If the interprocess_semaphore is posted the function
+ //!returns true. If there is an error throws sem_exception
+ bool timed_wait(const boost::posix_time::ptime &abs_time);
+
+ //!Returns the interprocess_semaphore count
+// int get_count() const;
+ /// @cond
+ private:
+ #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
+ #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
+ ipcdetail::spin_semaphore m_sem;
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ ipcdetail::windows_semaphore m_sem;
+ #else
+ #undef BOOST_INTERPROCESS_USE_POSIX
+ ipcdetail::posix_semaphore m_sem;
+ #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
+ /// @endcond
+};
+
+} //namespace interprocess {
+} //namespace boost {
+
+namespace boost {
+namespace interprocess {
+
+inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
+ : m_sem(initialCount)
+{}
+
+inline interprocess_semaphore::~interprocess_semaphore(){}
+
+inline void interprocess_semaphore::wait()
+{
+ #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_sem.timed_wait(wait_time))
+ {
+ throw interprocess_exception(timeout_when_waiting_error, "Interprocess semaphore timeout when waiting. Possible deadlock: owner died without posting?");
+ }
+ #else
+ m_sem.wait();
+ #endif
+}
+inline bool interprocess_semaphore::try_wait()
+{ return m_sem.try_wait(); }
+
+inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
+{ return m_sem.timed_wait(abs_time); }
+
+inline void interprocess_semaphore::post()
+{ m_sem.post(); }
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_SEMAPHORE_HPP