winapi_wrapper_common.hpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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/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. typedef typename microsec_clock<TimePoint>::time_point time_point;
  58. const time_point cur_time = microsec_clock<TimePoint>::universal_time();
  59. if(abs_time > cur_time){
  60. time_ms = static_cast<unsigned long>(duration_to_milliseconds(abs_time - cur_time));
  61. }
  62. }
  63. return do_winapi_wait(handle, time_ms);
  64. }
  65. inline void winapi_wrapper_wait_for_single_object(void *handle)
  66. {
  67. (void)do_winapi_wait(handle, winapi::infinite_time);
  68. }
  69. inline bool winapi_wrapper_try_wait_for_single_object(void *handle)
  70. {
  71. return do_winapi_wait(handle, 0u);
  72. }
  73. } //namespace ipcdetail {
  74. } //namespace interprocess {
  75. } //namespace boost {
  76. #include <boost/interprocess/detail/config_end.hpp>
  77. #endif //BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP