1 ////////////////////////////////////////////////////////////////////////////// 2 // 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) 6 // 7 // See http://www.boost.org/libs/interprocess for documentation. 8 // 9 ////////////////////////////////////////////////////////////////////////////// 10 11 #ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP 12 #define BOOST_INTERPROCESS_SEMAPHORE_HPP 13 14 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 15 16 #ifndef BOOST_CONFIG_HPP 17 # include <boost/config.hpp> 18 #endif 19 # 20 #if defined(BOOST_HAS_PRAGMA_ONCE) 21 # pragma once 22 #endif 23 24 #include <boost/interprocess/detail/config_begin.hpp> 25 #include <boost/interprocess/detail/workaround.hpp> 26 27 #include <boost/interprocess/creation_tags.hpp> 28 #include <boost/interprocess/exceptions.hpp> 29 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 30 #include <boost/interprocess/sync/detail/locks.hpp> 31 #include <boost/interprocess/sync/detail/common_algorithms.hpp> 32 33 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \ 34 (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES)) 35 #include <boost/interprocess/sync/posix/semaphore.hpp> 36 #define BOOST_INTERPROCESS_USE_POSIX 37 //Experimental... 38 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS) 39 #include <boost/interprocess/sync/windows/semaphore.hpp> 40 #define BOOST_INTERPROCESS_USE_WINDOWS 41 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 42 #include <boost/interprocess/sync/spin/semaphore.hpp> 43 #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION 44 #endif 45 46 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 47 48 //!\file 49 //!Describes a interprocess_semaphore class for inter-process synchronization 50 51 namespace boost { 52 namespace interprocess { 53 54 //!Wraps a interprocess_semaphore that can be placed in shared memory and can be 55 //!shared between processes. Allows timed lock tries 56 class interprocess_semaphore 57 { 58 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 59 //Non-copyable 60 interprocess_semaphore(const interprocess_semaphore &); 61 interprocess_semaphore &operator=(const interprocess_semaphore &); 62 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 63 public: 64 //!Creates a interprocess_semaphore with the given initial count. 65 //!interprocess_exception if there is an error.*/ 66 interprocess_semaphore(unsigned int initialCount); 67 68 //!Destroys the interprocess_semaphore. 69 //!Does not throw 70 ~interprocess_semaphore(); 71 72 //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting 73 //!for the interprocess_semaphore, then one of these processes will return successfully from 74 //!its wait function. If there is an error an interprocess_exception exception is thrown. 75 void post(); 76 77 //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero, 78 //!then the calling process/thread blocks until it can decrement the counter. 79 //!If there is an error an interprocess_exception exception is thrown. 80 void wait(); 81 82 //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero 83 //!and returns true. If the value is not greater than zero returns false. 84 //!If there is an error an interprocess_exception exception is thrown. 85 bool try_wait(); 86 87 //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater 88 //!than zero and returns true. Otherwise, waits for the interprocess_semaphore 89 //!to the posted or the timeout expires. If the timeout expires, the 90 //!function returns false. If the interprocess_semaphore is posted the function 91 //!returns true. If there is an error throws sem_exception 92 bool timed_wait(const boost::posix_time::ptime &abs_time); 93 94 //!Returns the interprocess_semaphore count 95 // int get_count() const; 96 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 97 private: 98 #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) 99 #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION 100 typedef ipcdetail::spin_semaphore internal_sem_t; 101 #elif defined(BOOST_INTERPROCESS_USE_WINDOWS) 102 #undef BOOST_INTERPROCESS_USE_WINDOWS 103 typedef ipcdetail::windows_semaphore internal_sem_t; 104 #else 105 #undef BOOST_INTERPROCESS_USE_POSIX 106 typedef ipcdetail::posix_semaphore internal_sem_t; 107 #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) 108 internal_sem_t m_sem; 109 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 110 }; 111 112 } //namespace interprocess { 113 } //namespace boost { 114 115 namespace boost { 116 namespace interprocess { 117 interprocess_semaphore(unsigned int initialCount)118inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount) 119 : m_sem(initialCount) 120 {} 121 ~interprocess_semaphore()122inline interprocess_semaphore::~interprocess_semaphore(){} 123 wait()124inline void interprocess_semaphore::wait() 125 { 126 ipcdetail::lock_to_wait<internal_sem_t> ltw(m_sem); 127 timeout_when_locking_aware_lock(ltw); 128 } 129 try_wait()130inline bool interprocess_semaphore::try_wait() 131 { return m_sem.try_wait(); } 132 timed_wait(const boost::posix_time::ptime & abs_time)133inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) 134 { return m_sem.timed_wait(abs_time); } 135 post()136inline void interprocess_semaphore::post() 137 { m_sem.post(); } 138 139 } //namespace interprocess { 140 } //namespace boost { 141 142 #include <boost/interprocess/detail/config_end.hpp> 143 144 #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP 145