winapi_wrapper_common.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. #ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
  11. #define BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #
  16. #if defined(BOOST_HAS_PRAGMA_ONCE)
  17. # pragma once
  18. #endif
  19. #include <boost/interprocess/detail/config_begin.hpp>
  20. #include <boost/interprocess/detail/workaround.hpp>
  21. #include <boost/interprocess/detail/win32_api.hpp>
  22. #include <boost/interprocess/errors.hpp>
  23. #include <boost/interprocess/exceptions.hpp>
  24. #include <boost/interprocess/detail/timed_utils.hpp>
  25. #include <limits>
  26. namespace boost {
  27. namespace interprocess {
  28. namespace ipcdetail {
  29. inline bool do_winapi_wait(void *handle, unsigned long dwMilliseconds)
  30. {
  31. unsigned long ret = winapi::wait_for_single_object(handle, dwMilliseconds);
  32. if(ret == winapi::wait_object_0){
  33. return true;
  34. }
  35. else if(ret == winapi::wait_timeout){
  36. return false;
  37. }
  38. else if(ret == winapi::wait_abandoned){ //Special case for orphaned mutexes
  39. winapi::release_mutex(handle);
  40. throw interprocess_exception(owner_dead_error);
  41. }
  42. else{
  43. error_info err = system_error_code();
  44. throw interprocess_exception(err);
  45. }
  46. }
  47. template<class TimePoint>
  48. inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const TimePoint &abs_time)
  49. {
  50. //Windows uses relative wait times so check for negative waits
  51. //and implement as 0 wait to allow try-semantics as POSIX mandates.
  52. unsigned long time_ms = 0u;
  53. if (ipcdetail::is_pos_infinity(abs_time)){
  54. time_ms = winapi::infinite_time;
  55. }
  56. else {
  57. const TimePoint cur_time = microsec_clock<TimePoint>::universal_time();
  58. if(abs_time > cur_time){
  59. time_ms = static_cast<unsigned long>(duration_to_milliseconds(abs_time - cur_time));
  60. }
  61. }
  62. return do_winapi_wait(handle, time_ms);
  63. }
  64. inline void winapi_wrapper_wait_for_single_object(void *handle)
  65. {
  66. (void)do_winapi_wait(handle, winapi::infinite_time);
  67. }
  68. inline bool winapi_wrapper_try_wait_for_single_object(void *handle)
  69. {
  70. return do_winapi_wait(handle, 0u);
  71. }
  72. } //namespace ipcdetail {
  73. } //namespace interprocess {
  74. } //namespace boost {
  75. #include <boost/interprocess/detail/config_end.hpp>
  76. #endif //BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP