recursive_lw_mutex.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* Copyright 2006-2023 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/flyweight for library home page.
  7. */
  8. #ifndef BOOST_FLYWEIGHT_DETAIL_RECURSIVE_LW_MUTEX_HPP
  9. #define BOOST_FLYWEIGHT_DETAIL_RECURSIVE_LW_MUTEX_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. /* Recursive lightweight mutex.
  14. * - If <mutex> is provided, it uses std::recursive_mutex.
  15. * - Else if Pthreads is available, it uses a Pthreads mutex with
  16. * PTHREAD_MUTEX_RECURSIVE attribute.
  17. * - Else if on Windows/Cygwin, it relies on boost::detail::lightweight_mutex
  18. * for an implementation based on (recursive) Win32 CRITICAL_SECTION.
  19. * - Else, it provides a dummy implementation.
  20. */
  21. #include <boost/config.hpp>
  22. #if !defined(BOOST_NO_CXX11_HDR_MUTEX)
  23. #include <boost/noncopyable.hpp>
  24. #include <mutex>
  25. namespace boost{
  26. namespace flyweights{
  27. namespace detail{
  28. struct recursive_lightweight_mutex:noncopyable
  29. {
  30. recursive_lightweight_mutex(){}
  31. struct scoped_lock;
  32. friend struct scoped_lock;
  33. struct scoped_lock:noncopyable
  34. {
  35. public:
  36. scoped_lock(recursive_lightweight_mutex& m):m_(m.m_){m_.lock();}
  37. ~scoped_lock(){m_.unlock();}
  38. private:
  39. std::recursive_mutex& m_;
  40. };
  41. private:
  42. std::recursive_mutex m_;
  43. };
  44. } /* namespace flyweights::detail */
  45. } /* namespace flyweights */
  46. } /* namespace boost */
  47. #elif defined(BOOST_HAS_PTHREADS)
  48. /* code shamelessly ripped from <boost/detail/lwm_pthreads.hpp> */
  49. #include <boost/assert.hpp>
  50. #include <boost/noncopyable.hpp>
  51. #include <pthread.h>
  52. namespace boost{
  53. namespace flyweights{
  54. namespace detail{
  55. struct recursive_lightweight_mutex:noncopyable
  56. {
  57. recursive_lightweight_mutex()
  58. {
  59. pthread_mutexattr_t attr;
  60. BOOST_VERIFY(pthread_mutexattr_init(&attr)==0);
  61. BOOST_VERIFY(pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE)==0);
  62. BOOST_VERIFY(pthread_mutex_init(&m_,&attr)==0);
  63. BOOST_VERIFY(pthread_mutexattr_destroy(&attr)==0);
  64. }
  65. ~recursive_lightweight_mutex(){pthread_mutex_destroy(&m_);}
  66. struct scoped_lock;
  67. friend struct scoped_lock;
  68. struct scoped_lock:noncopyable
  69. {
  70. public:
  71. scoped_lock(recursive_lightweight_mutex& m):m_(m.m_)
  72. {
  73. BOOST_VERIFY(pthread_mutex_lock(&m_)==0);
  74. }
  75. ~scoped_lock(){BOOST_VERIFY(pthread_mutex_unlock(&m_)==0);}
  76. private:
  77. pthread_mutex_t& m_;
  78. };
  79. private:
  80. pthread_mutex_t m_;
  81. };
  82. } /* namespace flyweights::detail */
  83. } /* namespace flyweights */
  84. } /* namespace boost */
  85. #elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
  86. #include <boost/smart_ptr/detail/lightweight_mutex.hpp>
  87. namespace boost{
  88. namespace flyweights{
  89. namespace detail{
  90. typedef boost::detail::lightweight_mutex recursive_lightweight_mutex;
  91. } /* namespace flyweights::detail */
  92. } /* namespace flyweights */
  93. } /* namespace boost */
  94. #else
  95. namespace boost{
  96. namespace flyweights{
  97. namespace detail{
  98. struct recursive_lightweight_mutex
  99. {
  100. typedef recursive_lightweight_mutex scoped_lock;
  101. };
  102. } /* namespace flyweights::detail */
  103. } /* namespace flyweights */
  104. } /* namespace boost */
  105. #endif
  106. #endif