pthread_helpers.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-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_PTHREAD_HELPERS_HPP
  11. #define BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP
  12. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif
  15. #include <boost/interprocess/detail/config_begin.hpp>
  16. #include <boost/interprocess/detail/workaround.hpp>
  17. #include <pthread.h>
  18. #include <errno.h>
  19. #include <boost/interprocess/exceptions.hpp>
  20. namespace boost {
  21. namespace interprocess {
  22. namespace ipcdetail{
  23. #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
  24. //!Makes pthread_mutexattr_t cleanup easy when using exceptions
  25. struct mutexattr_wrapper
  26. {
  27. //!Constructor
  28. mutexattr_wrapper(bool recursive = false)
  29. {
  30. if(pthread_mutexattr_init(&m_attr)!=0 ||
  31. pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 ||
  32. (recursive &&
  33. pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 ))
  34. throw interprocess_exception("pthread_mutexattr_xxxx failed");
  35. }
  36. //!Destructor
  37. ~mutexattr_wrapper() { pthread_mutexattr_destroy(&m_attr); }
  38. //!This allows using mutexattr_wrapper as pthread_mutexattr_t
  39. operator pthread_mutexattr_t&() { return m_attr; }
  40. pthread_mutexattr_t m_attr;
  41. };
  42. //!Makes pthread_condattr_t cleanup easy when using exceptions
  43. struct condattr_wrapper
  44. {
  45. //!Constructor
  46. condattr_wrapper()
  47. {
  48. if(pthread_condattr_init(&m_attr)!=0 ||
  49. pthread_condattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0)
  50. throw interprocess_exception("pthread_condattr_xxxx failed");
  51. }
  52. //!Destructor
  53. ~condattr_wrapper() { pthread_condattr_destroy(&m_attr); }
  54. //!This allows using condattr_wrapper as pthread_condattr_t
  55. operator pthread_condattr_t&(){ return m_attr; }
  56. pthread_condattr_t m_attr;
  57. };
  58. //!Makes initialized pthread_mutex_t cleanup easy when using exceptions
  59. class mutex_initializer
  60. {
  61. public:
  62. //!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex
  63. mutex_initializer(pthread_mutex_t &mut, pthread_mutexattr_t &mut_attr)
  64. : mp_mut(&mut)
  65. {
  66. if(pthread_mutex_init(mp_mut, &mut_attr) != 0)
  67. throw interprocess_exception("pthread_mutex_init failed");
  68. }
  69. ~mutex_initializer() { if(mp_mut) pthread_mutex_destroy(mp_mut); }
  70. void release() {mp_mut = 0; }
  71. private:
  72. pthread_mutex_t *mp_mut;
  73. };
  74. //!Makes initialized pthread_cond_t cleanup easy when using exceptions
  75. class condition_initializer
  76. {
  77. public:
  78. condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
  79. : mp_cond(&cond)
  80. {
  81. if(pthread_cond_init(mp_cond, &cond_attr)!= 0)
  82. throw interprocess_exception("pthread_cond_init failed");
  83. }
  84. ~condition_initializer() { if(mp_cond) pthread_cond_destroy(mp_cond); }
  85. void release() { mp_cond = 0; }
  86. private:
  87. pthread_cond_t *mp_cond;
  88. };
  89. #endif // #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
  90. #if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
  91. //!Makes pthread_barrierattr_t cleanup easy when using exceptions
  92. struct barrierattr_wrapper
  93. {
  94. //!Constructor
  95. barrierattr_wrapper()
  96. {
  97. if(pthread_barrierattr_init(&m_attr)!=0 ||
  98. pthread_barrierattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0)
  99. throw interprocess_exception("pthread_barrierattr_xxx failed");
  100. }
  101. //!Destructor
  102. ~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); }
  103. //!This allows using mutexattr_wrapper as pthread_barrierattr_t
  104. operator pthread_barrierattr_t&() { return m_attr; }
  105. pthread_barrierattr_t m_attr;
  106. };
  107. //!Makes initialized pthread_barrier_t cleanup easy when using exceptions
  108. class barrier_initializer
  109. {
  110. public:
  111. //!Constructor. Takes barrier attributes to initialize the barrier
  112. barrier_initializer(pthread_barrier_t &mut,
  113. pthread_barrierattr_t &mut_attr,
  114. int count)
  115. : mp_barrier(&mut)
  116. {
  117. if(pthread_barrier_init(mp_barrier, &mut_attr, count) != 0)
  118. throw interprocess_exception("pthread_barrier_init failed");
  119. }
  120. ~barrier_initializer() { if(mp_barrier) pthread_barrier_destroy(mp_barrier); }
  121. void release() {mp_barrier = 0; }
  122. private:
  123. pthread_barrier_t *mp_barrier;
  124. };
  125. #endif //#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
  126. }//namespace ipcdetail
  127. }//namespace interprocess
  128. }//namespace boost
  129. #include <boost/interprocess/detail/config_end.hpp>
  130. #endif //ifdef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP