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_WRAPPER_COMMON_HPP 12 #define BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_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/win32_api.hpp> 25 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 26 #include <boost/interprocess/errors.hpp> 27 #include <boost/interprocess/exceptions.hpp> 28 #include <limits> 29 30 namespace boost { 31 namespace interprocess { 32 namespace ipcdetail { 33 do_winapi_wait(void * handle,unsigned long dwMilliseconds)34inline bool do_winapi_wait(void *handle, unsigned long dwMilliseconds) 35 { 36 unsigned long ret = winapi::wait_for_single_object(handle, dwMilliseconds); 37 if(ret == winapi::wait_object_0){ 38 return true; 39 } 40 else if(ret == winapi::wait_timeout){ 41 return false; 42 } 43 else if(ret == winapi::wait_abandoned){ //Special case for orphaned mutexes 44 winapi::release_mutex(handle); 45 throw interprocess_exception(owner_dead_error); 46 } 47 else{ 48 error_info err = system_error_code(); 49 throw interprocess_exception(err); 50 } 51 } 52 winapi_wrapper_timed_wait_for_single_object(void * handle,const boost::posix_time::ptime & abs_time)53inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &abs_time) 54 { 55 //Windows uses relative wait times so check for negative waits 56 //and implement as 0 wait to allow try-semantics as POSIX mandates. 57 unsigned long time = 0u; 58 if (abs_time.is_pos_infinity()){ 59 time = winapi::infinite_time; 60 } 61 else { 62 const boost::posix_time::ptime cur_time = microsec_clock::universal_time(); 63 if(abs_time > cur_time){ 64 time = (abs_time - cur_time).total_milliseconds(); 65 } 66 } 67 return do_winapi_wait(handle, time); 68 } 69 winapi_wrapper_wait_for_single_object(void * handle)70inline void winapi_wrapper_wait_for_single_object(void *handle) 71 { 72 (void)do_winapi_wait(handle, winapi::infinite_time); 73 } 74 winapi_wrapper_try_wait_for_single_object(void * handle)75inline bool winapi_wrapper_try_wait_for_single_object(void *handle) 76 { 77 return do_winapi_wait(handle, 0u); 78 } 79 80 } //namespace ipcdetail { 81 } //namespace interprocess { 82 } //namespace boost { 83 84 #include <boost/interprocess/detail/config_end.hpp> 85 86 #endif //BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP 87