1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP
12 #define BOOST_INTERPROCESS_SEMAPHORE_HPP
14 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
16 #ifndef BOOST_CONFIG_HPP
17 # include <boost/config.hpp>
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
24 #include <boost/interprocess/detail/config_begin.hpp>
25 #include <boost/interprocess/detail/workaround.hpp>
27 #include <boost/interprocess/creation_tags.hpp>
28 #include <boost/interprocess/exceptions.hpp>
29 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
31 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
32 (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES))
33 #include <boost/interprocess/sync/posix/semaphore.hpp>
34 #define BOOST_INTERPROCESS_USE_POSIX
36 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
37 #include <boost/interprocess/sync/windows/semaphore.hpp>
38 #define BOOST_INTERPROCESS_USE_WINDOWS
39 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
40 #include <boost/interprocess/sync/spin/semaphore.hpp>
41 #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
44 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
47 //!Describes a interprocess_semaphore class for inter-process synchronization
50 namespace interprocess {
52 //!Wraps a interprocess_semaphore that can be placed in shared memory and can be
53 //!shared between processes. Allows timed lock tries
54 class interprocess_semaphore
56 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
58 interprocess_semaphore(const interprocess_semaphore &);
59 interprocess_semaphore &operator=(const interprocess_semaphore &);
60 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
62 //!Creates a interprocess_semaphore with the given initial count.
63 //!interprocess_exception if there is an error.*/
64 interprocess_semaphore(unsigned int initialCount);
66 //!Destroys the interprocess_semaphore.
68 ~interprocess_semaphore();
70 //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
71 //!for the interprocess_semaphore, then one of these processes will return successfully from
72 //!its wait function. If there is an error an interprocess_exception exception is thrown.
75 //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
76 //!then the calling process/thread blocks until it can decrement the counter.
77 //!If there is an error an interprocess_exception exception is thrown.
80 //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
81 //!and returns true. If the value is not greater than zero returns false.
82 //!If there is an error an interprocess_exception exception is thrown.
85 //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
86 //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
87 //!to the posted or the timeout expires. If the timeout expires, the
88 //!function returns false. If the interprocess_semaphore is posted the function
89 //!returns true. If there is an error throws sem_exception
90 bool timed_wait(const boost::posix_time::ptime &abs_time);
92 //!Returns the interprocess_semaphore count
93 // int get_count() const;
94 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
96 #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
97 #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
98 ipcdetail::spin_semaphore m_sem;
99 #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
100 #undef BOOST_INTERPROCESS_USE_WINDOWS
101 ipcdetail::windows_semaphore m_sem;
103 #undef BOOST_INTERPROCESS_USE_POSIX
104 ipcdetail::posix_semaphore m_sem;
105 #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
106 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
109 } //namespace interprocess {
110 } //namespace boost {
113 namespace interprocess {
115 inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
116 : m_sem(initialCount)
119 inline interprocess_semaphore::~interprocess_semaphore(){}
121 inline void interprocess_semaphore::wait()
123 #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
124 boost::posix_time::ptime wait_time
125 = microsec_clock::universal_time()
126 + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
127 if (!m_sem.timed_wait(wait_time))
129 throw interprocess_exception(timeout_when_waiting_error, "Interprocess semaphore timeout when waiting. Possible deadlock: owner died without posting?");
135 inline bool interprocess_semaphore::try_wait()
136 { return m_sem.try_wait(); }
138 inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
139 { return m_sem.timed_wait(abs_time); }
141 inline void interprocess_semaphore::post()
144 } //namespace interprocess {
145 } //namespace boost {
147 #include <boost/interprocess/detail/config_end.hpp>
149 #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP