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