1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2011-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_WINAPI_SEMAPHORE_WRAPPER_HPP 12 #define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_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/creation_tags.hpp> 25 #include <boost/interprocess/permissions.hpp> 26 #include <boost/interprocess/detail/win32_api.hpp> 27 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 28 #include <boost/interprocess/sync/windows/winapi_wrapper_common.hpp> 29 #include <boost/interprocess/errors.hpp> 30 #include <boost/interprocess/exceptions.hpp> 31 #include <limits> 32 33 namespace boost { 34 namespace interprocess { 35 namespace ipcdetail { 36 37 class winapi_semaphore_functions 38 { 39 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 40 41 //Non-copyable 42 winapi_semaphore_functions(const winapi_semaphore_functions &); 43 winapi_semaphore_functions &operator=(const winapi_semaphore_functions &); 44 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 45 46 public: winapi_semaphore_functions(void * hnd)47 winapi_semaphore_functions(void *hnd) 48 : m_sem_hnd(hnd) 49 {} 50 post(long count=1)51 void post(long count = 1) 52 { 53 long prev_count; 54 winapi::release_semaphore(m_sem_hnd, count, &prev_count); 55 } 56 wait()57 void wait() 58 { return winapi_wrapper_wait_for_single_object(m_sem_hnd); } 59 try_wait()60 bool try_wait() 61 { return winapi_wrapper_try_wait_for_single_object(m_sem_hnd); } 62 timed_wait(const boost::posix_time::ptime & abs_time)63 bool timed_wait(const boost::posix_time::ptime &abs_time) 64 { return winapi_wrapper_timed_wait_for_single_object(m_sem_hnd, abs_time); } 65 value() const66 long value() const 67 { 68 long l_count, l_limit; 69 if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit)) 70 return 0; 71 return l_count; 72 } 73 limit() const74 long limit() const 75 { 76 long l_count, l_limit; 77 if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit)) 78 return 0; 79 return l_limit; 80 } 81 82 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 83 protected: 84 void *m_sem_hnd; 85 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 86 }; 87 88 89 //Swappable semaphore wrapper 90 class winapi_semaphore_wrapper 91 : public winapi_semaphore_functions 92 { 93 winapi_semaphore_wrapper(const winapi_semaphore_wrapper &); 94 winapi_semaphore_wrapper &operator=(const winapi_semaphore_wrapper &); 95 96 public: 97 98 //Long is 32 bits in windows 99 static const long MaxCount = long(0x7FFFFFFF); 100 winapi_semaphore_wrapper(void * hnd=winapi::invalid_handle_value)101 winapi_semaphore_wrapper(void *hnd = winapi::invalid_handle_value) 102 : winapi_semaphore_functions(hnd) 103 {} 104 ~winapi_semaphore_wrapper()105 ~winapi_semaphore_wrapper() 106 { this->close(); } 107 release()108 void *release() 109 { 110 void *hnd = m_sem_hnd; 111 m_sem_hnd = winapi::invalid_handle_value; 112 return hnd; 113 } 114 handle() const115 void *handle() const 116 { return m_sem_hnd; } 117 open_or_create(const char * name,long sem_count,long max_count,const permissions & perm,bool & created)118 bool open_or_create( const char *name 119 , long sem_count 120 , long max_count 121 , const permissions &perm 122 , bool &created) 123 { 124 if(m_sem_hnd == winapi::invalid_handle_value){ 125 m_sem_hnd = winapi::open_or_create_semaphore 126 ( name 127 , sem_count 128 , max_count 129 , (winapi::interprocess_security_attributes*)perm.get_permissions() 130 ); 131 created = winapi::get_last_error() != winapi::error_already_exists; 132 return m_sem_hnd != winapi::invalid_handle_value; 133 } 134 else{ 135 return false; 136 } 137 } 138 open_semaphore(const char * name)139 bool open_semaphore(const char *name) 140 { 141 if(m_sem_hnd == winapi::invalid_handle_value){ 142 m_sem_hnd = winapi::open_semaphore(name); 143 return m_sem_hnd != winapi::invalid_handle_value; 144 } 145 else{ 146 return false; 147 } 148 } 149 close()150 void close() 151 { 152 if(m_sem_hnd != winapi::invalid_handle_value){ 153 winapi::close_handle(m_sem_hnd); 154 m_sem_hnd = winapi::invalid_handle_value; 155 } 156 } 157 swap(winapi_semaphore_wrapper & other)158 void swap(winapi_semaphore_wrapper &other) 159 { void *tmp = m_sem_hnd; m_sem_hnd = other.m_sem_hnd; other.m_sem_hnd = tmp; } 160 }; 161 162 } //namespace ipcdetail { 163 } //namespace interprocess { 164 } //namespace boost { 165 166 #include <boost/interprocess/detail/config_end.hpp> 167 168 #endif //BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP 169