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_DETAIL_WINDOWS_SEMAPHORE_HPP 12 #define BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP 13 14 #ifndef BOOST_CONFIG_HPP 15 # include <boost/config.hpp> 16 #endif 17 # 18 #if defined(BOOST_HAS_PRAGMA_ONCE) 19 # pragma once 20 #endif 21 22 #include <boost/interprocess/detail/config_begin.hpp> 23 #include <boost/interprocess/detail/workaround.hpp> 24 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 25 #include <boost/interprocess/detail/win32_api.hpp> 26 #include <boost/interprocess/detail/windows_intermodule_singleton.hpp> 27 #include <boost/interprocess/sync/windows/sync_utils.hpp> 28 #include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp> 29 #include <boost/interprocess/exceptions.hpp> 30 #include <boost/assert.hpp> 31 32 33 namespace boost { 34 namespace interprocess { 35 namespace ipcdetail { 36 37 class windows_semaphore 38 { 39 windows_semaphore(const windows_semaphore &); 40 windows_semaphore &operator=(const windows_semaphore &); 41 public: 42 43 windows_semaphore(unsigned int initialCount); 44 ~windows_semaphore(); 45 46 void post(long release_count = 1); 47 void wait(); 48 bool try_wait(); 49 bool timed_wait(const boost::posix_time::ptime &abs_time); 50 51 private: 52 const sync_id id_; 53 }; 54 windows_semaphore(unsigned int initialCount)55inline windows_semaphore::windows_semaphore(unsigned int initialCount) 56 : id_(this) 57 { 58 sync_handles &handles = 59 windows_intermodule_singleton<sync_handles>::get(); 60 //Force smeaphore creation with the initial count 61 bool open_or_created; 62 handles.obtain_semaphore(this->id_, initialCount, &open_or_created); 63 //The semaphore must be created, never opened 64 BOOST_ASSERT(open_or_created); 65 BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists); 66 (void)open_or_created; 67 } 68 ~windows_semaphore()69inline windows_semaphore::~windows_semaphore() 70 { 71 sync_handles &handles = 72 windows_intermodule_singleton<sync_handles>::get(); 73 handles.destroy_handle(this->id_); 74 } 75 wait(void)76inline void windows_semaphore::wait(void) 77 { 78 sync_handles &handles = 79 windows_intermodule_singleton<sync_handles>::get(); 80 //This can throw 81 winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0)); 82 sem.wait(); 83 } 84 try_wait(void)85inline bool windows_semaphore::try_wait(void) 86 { 87 sync_handles &handles = 88 windows_intermodule_singleton<sync_handles>::get(); 89 //This can throw 90 winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0)); 91 return sem.try_wait(); 92 } 93 timed_wait(const boost::posix_time::ptime & abs_time)94inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time) 95 { 96 sync_handles &handles = 97 windows_intermodule_singleton<sync_handles>::get(); 98 //This can throw 99 winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0)); 100 return sem.timed_wait(abs_time); 101 } 102 post(long release_count)103inline void windows_semaphore::post(long release_count) 104 { 105 sync_handles &handles = 106 windows_intermodule_singleton<sync_handles>::get(); 107 winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0)); 108 sem.post(release_count); 109 } 110 111 } //namespace ipcdetail { 112 } //namespace interprocess { 113 } //namespace boost { 114 115 #include <boost/interprocess/detail/config_end.hpp> 116 117 #endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP 118