• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)34 inline 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)53 inline 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)70 inline 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)75 inline 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