win_mutex.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //
  2. // win_mutex.hpp
  3. // ~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_WIN_MUTEX_HPP
  11. #define ASIO_DETAIL_WIN_MUTEX_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/push_options.hpp"
  16. #include "asio/detail/push_options.hpp"
  17. #include <boost/config.hpp>
  18. #include "asio/detail/pop_options.hpp"
  19. #if defined(BOOST_WINDOWS)
  20. #include "asio/error.hpp"
  21. #include "asio/system_error.hpp"
  22. #include "asio/detail/noncopyable.hpp"
  23. #include "asio/detail/socket_types.hpp"
  24. #include "asio/detail/scoped_lock.hpp"
  25. #include "asio/detail/push_options.hpp"
  26. #include <boost/throw_exception.hpp>
  27. #include "asio/detail/pop_options.hpp"
  28. namespace asio {
  29. namespace detail {
  30. class win_mutex
  31. : private noncopyable
  32. {
  33. public:
  34. typedef asio::detail::scoped_lock<win_mutex> scoped_lock;
  35. // Constructor.
  36. win_mutex()
  37. {
  38. int error = do_init();
  39. if (error != 0)
  40. {
  41. asio::system_error e(
  42. asio::error_code(error,
  43. asio::error::get_system_category()),
  44. "mutex");
  45. boost::throw_exception(e);
  46. }
  47. }
  48. // Destructor.
  49. ~win_mutex()
  50. {
  51. ::DeleteCriticalSection(&crit_section_);
  52. }
  53. // Lock the mutex.
  54. void lock()
  55. {
  56. ::EnterCriticalSection(&crit_section_);
  57. }
  58. // Unlock the mutex.
  59. void unlock()
  60. {
  61. ::LeaveCriticalSection(&crit_section_);
  62. }
  63. private:
  64. // Initialisation must be performed in a separate function to the constructor
  65. // since the compiler does not support the use of structured exceptions and
  66. // C++ exceptions in the same function.
  67. int do_init()
  68. {
  69. #if defined(__MINGW32__)
  70. // Not sure if MinGW supports structured exception handling, so for now
  71. // we'll just call the Windows API and hope.
  72. # if defined(UNDER_CE)
  73. ::InitializeCriticalSection(&crit_section_);
  74. # else
  75. ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
  76. # endif
  77. return 0;
  78. #else
  79. __try
  80. {
  81. # if defined(UNDER_CE)
  82. ::InitializeCriticalSection(&crit_section_);
  83. # else
  84. ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
  85. # endif
  86. }
  87. __except(GetExceptionCode() == STATUS_NO_MEMORY
  88. ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  89. {
  90. return ERROR_OUTOFMEMORY;
  91. }
  92. return 0;
  93. #endif
  94. }
  95. ::CRITICAL_SECTION crit_section_;
  96. };
  97. } // namespace detail
  98. } // namespace asio
  99. #endif // defined(BOOST_WINDOWS)
  100. #include "asio/detail/pop_options.hpp"
  101. #endif // ASIO_DETAIL_WIN_MUTEX_HPP