1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2005-2009. 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 11 #ifndef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP 12 #define BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP 13 14 #if (defined _MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif 17 18 #include <boost/interprocess/detail/config_begin.hpp> 19 #include <boost/interprocess/detail/workaround.hpp> 20 21 #include <pthread.h> 22 #include <errno.h> 23 #include <boost/interprocess/exceptions.hpp> 24 25 namespace boost { 26 namespace interprocess { 27 namespace detail{ 28 29 #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED 30 31 //!Makes pthread_mutexattr_t cleanup easy when using exceptions 32 struct mutexattr_wrapper 33 { 34 //!Constructor mutexattr_wrapperboost::interprocess::detail::mutexattr_wrapper35 mutexattr_wrapper(bool recursive = false) 36 { 37 if(pthread_mutexattr_init(&m_attr)!=0 || 38 pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 || 39 (recursive && 40 pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 )) 41 throw interprocess_exception("pthread_mutexattr_xxxx failed"); 42 } 43 44 //!Destructor ~mutexattr_wrapperboost::interprocess::detail::mutexattr_wrapper45 ~mutexattr_wrapper() { pthread_mutexattr_destroy(&m_attr); } 46 47 //!This allows using mutexattr_wrapper as pthread_mutexattr_t operator pthread_mutexattr_t&boost::interprocess::detail::mutexattr_wrapper48 operator pthread_mutexattr_t&() { return m_attr; } 49 50 pthread_mutexattr_t m_attr; 51 }; 52 53 //!Makes pthread_condattr_t cleanup easy when using exceptions 54 struct condattr_wrapper 55 { 56 //!Constructor condattr_wrapperboost::interprocess::detail::condattr_wrapper57 condattr_wrapper() 58 { 59 if(pthread_condattr_init(&m_attr)!=0 || 60 pthread_condattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0) 61 throw interprocess_exception("pthread_condattr_xxxx failed"); 62 } 63 64 //!Destructor ~condattr_wrapperboost::interprocess::detail::condattr_wrapper65 ~condattr_wrapper() { pthread_condattr_destroy(&m_attr); } 66 67 //!This allows using condattr_wrapper as pthread_condattr_t operator pthread_condattr_t&boost::interprocess::detail::condattr_wrapper68 operator pthread_condattr_t&(){ return m_attr; } 69 70 pthread_condattr_t m_attr; 71 }; 72 73 //!Makes initialized pthread_mutex_t cleanup easy when using exceptions 74 class mutex_initializer 75 { 76 public: 77 //!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex mutex_initializer(pthread_mutex_t & mut,pthread_mutexattr_t & mut_attr)78 mutex_initializer(pthread_mutex_t &mut, pthread_mutexattr_t &mut_attr) 79 : mp_mut(&mut) 80 { 81 if(pthread_mutex_init(mp_mut, &mut_attr) != 0) 82 throw interprocess_exception("pthread_mutex_init failed"); 83 } 84 ~mutex_initializer()85 ~mutex_initializer() { if(mp_mut) pthread_mutex_destroy(mp_mut); } 86 release()87 void release() {mp_mut = 0; } 88 89 private: 90 pthread_mutex_t *mp_mut; 91 }; 92 93 //!Makes initialized pthread_cond_t cleanup easy when using exceptions 94 class condition_initializer 95 { 96 public: condition_initializer(pthread_cond_t & cond,pthread_condattr_t & cond_attr)97 condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr) 98 : mp_cond(&cond) 99 { 100 if(pthread_cond_init(mp_cond, &cond_attr)!= 0) 101 throw interprocess_exception("pthread_cond_init failed"); 102 } 103 ~condition_initializer()104 ~condition_initializer() { if(mp_cond) pthread_cond_destroy(mp_cond); } 105 release()106 void release() { mp_cond = 0; } 107 108 private: 109 pthread_cond_t *mp_cond; 110 }; 111 112 #endif // #if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED 113 114 #if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) 115 116 //!Makes pthread_barrierattr_t cleanup easy when using exceptions 117 struct barrierattr_wrapper 118 { 119 //!Constructor barrierattr_wrapperboost::interprocess::detail::barrierattr_wrapper120 barrierattr_wrapper() 121 { 122 if(pthread_barrierattr_init(&m_attr)!=0 || 123 pthread_barrierattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0) 124 throw interprocess_exception("pthread_barrierattr_xxx failed"); 125 } 126 127 //!Destructor ~barrierattr_wrapperboost::interprocess::detail::barrierattr_wrapper128 ~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); } 129 130 //!This allows using mutexattr_wrapper as pthread_barrierattr_t operator pthread_barrierattr_t&boost::interprocess::detail::barrierattr_wrapper131 operator pthread_barrierattr_t&() { return m_attr; } 132 133 pthread_barrierattr_t m_attr; 134 }; 135 136 //!Makes initialized pthread_barrier_t cleanup easy when using exceptions 137 class barrier_initializer 138 { 139 public: 140 //!Constructor. Takes barrier attributes to initialize the barrier barrier_initializer(pthread_barrier_t & mut,pthread_barrierattr_t & mut_attr,int count)141 barrier_initializer(pthread_barrier_t &mut, 142 pthread_barrierattr_t &mut_attr, 143 int count) 144 : mp_barrier(&mut) 145 { 146 if(pthread_barrier_init(mp_barrier, &mut_attr, count) != 0) 147 throw interprocess_exception("pthread_barrier_init failed"); 148 } 149 ~barrier_initializer()150 ~barrier_initializer() { if(mp_barrier) pthread_barrier_destroy(mp_barrier); } 151 release()152 void release() {mp_barrier = 0; } 153 154 private: 155 pthread_barrier_t *mp_barrier; 156 }; 157 158 #endif //#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) 159 160 }//namespace detail 161 162 }//namespace interprocess 163 164 }//namespace boost 165 166 #include <boost/interprocess/detail/config_end.hpp> 167 168 #endif //ifdef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP 169