annotate DEPENDENCIES/generic/include/boost/thread/pthread/mutex.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
Chris@16 2 #define BOOST_THREAD_PTHREAD_MUTEX_HPP
Chris@16 3 // (C) Copyright 2007-8 Anthony Williams
Chris@101 4 // (C) Copyright 2011,2012,2015 Vicente J. Botet Escriba
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #include <boost/thread/detail/config.hpp>
Chris@101 10 #include <boost/assert.hpp>
Chris@16 11 #include <pthread.h>
Chris@16 12 #include <boost/throw_exception.hpp>
Chris@101 13 #include <boost/core/ignore_unused.hpp>
Chris@16 14 #include <boost/thread/exceptions.hpp>
Chris@16 15 #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
Chris@16 16 #include <boost/thread/lock_types.hpp>
Chris@16 17 #endif
Chris@16 18 #include <boost/thread/thread_time.hpp>
Chris@16 19 #include <boost/thread/xtime.hpp>
Chris@16 20 #include <boost/assert.hpp>
Chris@16 21 #include <errno.h>
Chris@16 22 #include <boost/thread/pthread/timespec.hpp>
Chris@16 23 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
Chris@16 24 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 25 #include <boost/chrono/system_clocks.hpp>
Chris@16 26 #include <boost/chrono/ceil.hpp>
Chris@16 27 #endif
Chris@16 28 #include <boost/thread/detail/delete.hpp>
Chris@16 29
Chris@101 30 #if (defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0)>=200112L) \
Chris@101 31 || (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
Chris@16 32 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 33 #define BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 34 #endif
Chris@16 35 #endif
Chris@16 36
Chris@16 37
Chris@16 38 #include <boost/config/abi_prefix.hpp>
Chris@16 39
Chris@16 40 #ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
Chris@16 41 #define BOOST_THREAD_HAS_EINTR_BUG
Chris@16 42 #endif
Chris@16 43
Chris@16 44 namespace boost
Chris@16 45 {
Chris@16 46 namespace posix {
Chris@16 47 #ifdef BOOST_THREAD_HAS_EINTR_BUG
Chris@16 48 BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
Chris@16 49 {
Chris@16 50 int ret;
Chris@16 51 do
Chris@16 52 {
Chris@16 53 ret = ::pthread_mutex_destroy(m);
Chris@16 54 } while (ret == EINTR);
Chris@16 55 return ret;
Chris@16 56 }
Chris@16 57 BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
Chris@16 58 {
Chris@16 59 int ret;
Chris@16 60 do
Chris@16 61 {
Chris@16 62 ret = ::pthread_mutex_lock(m);
Chris@16 63 } while (ret == EINTR);
Chris@16 64 return ret;
Chris@16 65 }
Chris@16 66 BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
Chris@16 67 {
Chris@16 68 int ret;
Chris@16 69 do
Chris@16 70 {
Chris@16 71 ret = ::pthread_mutex_unlock(m);
Chris@16 72 } while (ret == EINTR);
Chris@16 73 return ret;
Chris@16 74 }
Chris@16 75 #else
Chris@16 76 BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
Chris@16 77 {
Chris@16 78 return ::pthread_mutex_destroy(m);
Chris@16 79 }
Chris@16 80 BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
Chris@16 81 {
Chris@16 82 return ::pthread_mutex_lock(m);
Chris@16 83 }
Chris@16 84 BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
Chris@16 85 {
Chris@16 86 return ::pthread_mutex_unlock(m);
Chris@16 87 }
Chris@16 88
Chris@16 89 #endif
Chris@16 90
Chris@16 91 }
Chris@16 92 class mutex
Chris@16 93 {
Chris@16 94 private:
Chris@16 95 pthread_mutex_t m;
Chris@16 96 public:
Chris@16 97 BOOST_THREAD_NO_COPYABLE(mutex)
Chris@16 98
Chris@16 99 mutex()
Chris@16 100 {
Chris@16 101 int const res=pthread_mutex_init(&m,NULL);
Chris@16 102 if(res)
Chris@16 103 {
Chris@16 104 boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
Chris@16 105 }
Chris@16 106 }
Chris@16 107 ~mutex()
Chris@16 108 {
Chris@101 109 int const res = posix::pthread_mutex_destroy(&m);
Chris@101 110 boost::ignore_unused(res);
Chris@101 111 BOOST_ASSERT(!res);
Chris@16 112 }
Chris@16 113
Chris@16 114 void lock()
Chris@16 115 {
Chris@16 116 int res = posix::pthread_mutex_lock(&m);
Chris@16 117 if (res)
Chris@16 118 {
Chris@16 119 boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
Chris@16 120 }
Chris@16 121 }
Chris@16 122
Chris@16 123 void unlock()
Chris@16 124 {
Chris@16 125 int res = posix::pthread_mutex_unlock(&m);
Chris@101 126 (void)res;
Chris@101 127 BOOST_ASSERT(res == 0);
Chris@101 128 // if (res)
Chris@101 129 // {
Chris@101 130 // boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
Chris@101 131 // }
Chris@16 132 }
Chris@16 133
Chris@16 134 bool try_lock()
Chris@16 135 {
Chris@16 136 int res;
Chris@16 137 do
Chris@16 138 {
Chris@16 139 res = pthread_mutex_trylock(&m);
Chris@16 140 } while (res == EINTR);
Chris@16 141 if (res==EBUSY)
Chris@16 142 {
Chris@16 143 return false;
Chris@16 144 }
Chris@16 145
Chris@16 146 return !res;
Chris@16 147 }
Chris@16 148
Chris@16 149 #define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE
Chris@16 150 typedef pthread_mutex_t* native_handle_type;
Chris@16 151 native_handle_type native_handle()
Chris@16 152 {
Chris@16 153 return &m;
Chris@16 154 }
Chris@16 155
Chris@16 156 #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
Chris@16 157 typedef unique_lock<mutex> scoped_lock;
Chris@16 158 typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
Chris@16 159 #endif
Chris@16 160 };
Chris@16 161
Chris@16 162 typedef mutex try_mutex;
Chris@16 163
Chris@16 164 class timed_mutex
Chris@16 165 {
Chris@16 166 private:
Chris@16 167 pthread_mutex_t m;
Chris@16 168 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 169 pthread_cond_t cond;
Chris@16 170 bool is_locked;
Chris@16 171 #endif
Chris@16 172 public:
Chris@16 173 BOOST_THREAD_NO_COPYABLE(timed_mutex)
Chris@16 174 timed_mutex()
Chris@16 175 {
Chris@16 176 int const res=pthread_mutex_init(&m,NULL);
Chris@16 177 if(res)
Chris@16 178 {
Chris@16 179 boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
Chris@16 180 }
Chris@16 181 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 182 int const res2=pthread_cond_init(&cond,NULL);
Chris@16 183 if(res2)
Chris@16 184 {
Chris@16 185 BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
Chris@16 186 //BOOST_VERIFY(!pthread_mutex_destroy(&m));
Chris@16 187 boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
Chris@16 188 }
Chris@16 189 is_locked=false;
Chris@16 190 #endif
Chris@16 191 }
Chris@16 192 ~timed_mutex()
Chris@16 193 {
Chris@16 194 BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
Chris@16 195 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 196 BOOST_VERIFY(!pthread_cond_destroy(&cond));
Chris@16 197 #endif
Chris@16 198 }
Chris@16 199
Chris@16 200 #if defined BOOST_THREAD_USES_DATETIME
Chris@16 201 template<typename TimeDuration>
Chris@16 202 bool timed_lock(TimeDuration const & relative_time)
Chris@16 203 {
Chris@16 204 return timed_lock(get_system_time()+relative_time);
Chris@16 205 }
Chris@16 206 bool timed_lock(boost::xtime const & absolute_time)
Chris@16 207 {
Chris@16 208 return timed_lock(system_time(absolute_time));
Chris@16 209 }
Chris@16 210 #endif
Chris@16 211 #ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
Chris@16 212 void lock()
Chris@16 213 {
Chris@16 214 int res = posix::pthread_mutex_lock(&m);
Chris@16 215 if (res)
Chris@16 216 {
Chris@16 217 boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
Chris@16 218 }
Chris@16 219 }
Chris@16 220
Chris@16 221 void unlock()
Chris@16 222 {
Chris@16 223 int res = posix::pthread_mutex_unlock(&m);
Chris@101 224 (void)res;
Chris@101 225 BOOST_ASSERT(res == 0);
Chris@101 226 // if (res)
Chris@101 227 // {
Chris@101 228 // boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
Chris@101 229 // }
Chris@16 230 }
Chris@16 231
Chris@16 232 bool try_lock()
Chris@16 233 {
Chris@16 234 int res;
Chris@16 235 do
Chris@16 236 {
Chris@16 237 res = pthread_mutex_trylock(&m);
Chris@16 238 } while (res == EINTR);
Chris@16 239 if (res==EBUSY)
Chris@16 240 {
Chris@16 241 return false;
Chris@16 242 }
Chris@16 243
Chris@16 244 return !res;
Chris@16 245 }
Chris@16 246
Chris@16 247
Chris@16 248 private:
Chris@16 249 bool do_try_lock_until(struct timespec const &timeout)
Chris@16 250 {
Chris@16 251 int const res=pthread_mutex_timedlock(&m,&timeout);
Chris@16 252 BOOST_ASSERT(!res || res==ETIMEDOUT);
Chris@16 253 return !res;
Chris@16 254 }
Chris@16 255 public:
Chris@16 256
Chris@16 257 #else
Chris@16 258 void lock()
Chris@16 259 {
Chris@16 260 boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
Chris@16 261 while(is_locked)
Chris@16 262 {
Chris@16 263 BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
Chris@16 264 }
Chris@16 265 is_locked=true;
Chris@16 266 }
Chris@16 267
Chris@16 268 void unlock()
Chris@16 269 {
Chris@16 270 boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
Chris@16 271 is_locked=false;
Chris@16 272 BOOST_VERIFY(!pthread_cond_signal(&cond));
Chris@16 273 }
Chris@16 274
Chris@16 275 bool try_lock()
Chris@16 276 {
Chris@16 277 boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
Chris@16 278 if(is_locked)
Chris@16 279 {
Chris@16 280 return false;
Chris@16 281 }
Chris@16 282 is_locked=true;
Chris@16 283 return true;
Chris@16 284 }
Chris@16 285
Chris@16 286 private:
Chris@16 287 bool do_try_lock_until(struct timespec const &timeout)
Chris@16 288 {
Chris@16 289 boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
Chris@16 290 while(is_locked)
Chris@16 291 {
Chris@16 292 int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
Chris@16 293 if(cond_res==ETIMEDOUT)
Chris@16 294 {
Chris@16 295 return false;
Chris@16 296 }
Chris@16 297 BOOST_ASSERT(!cond_res);
Chris@16 298 }
Chris@16 299 is_locked=true;
Chris@16 300 return true;
Chris@16 301 }
Chris@16 302 public:
Chris@16 303 #endif
Chris@16 304
Chris@16 305 #if defined BOOST_THREAD_USES_DATETIME
Chris@16 306 bool timed_lock(system_time const & abs_time)
Chris@16 307 {
Chris@16 308 struct timespec const ts=boost::detail::to_timespec(abs_time);
Chris@16 309 return do_try_lock_until(ts);
Chris@16 310 }
Chris@16 311 #endif
Chris@16 312 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 313 template <class Rep, class Period>
Chris@16 314 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
Chris@16 315 {
Chris@16 316 return try_lock_until(chrono::steady_clock::now() + rel_time);
Chris@16 317 }
Chris@16 318 template <class Clock, class Duration>
Chris@16 319 bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
Chris@16 320 {
Chris@16 321 using namespace chrono;
Chris@16 322 system_clock::time_point s_now = system_clock::now();
Chris@16 323 typename Clock::time_point c_now = Clock::now();
Chris@16 324 return try_lock_until(s_now + ceil<nanoseconds>(t - c_now));
Chris@16 325 }
Chris@16 326 template <class Duration>
Chris@16 327 bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
Chris@16 328 {
Chris@16 329 using namespace chrono;
Chris@16 330 typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
Chris@16 331 return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
Chris@16 332 }
Chris@16 333 bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
Chris@16 334 {
Chris@16 335 //using namespace chrono;
Chris@16 336 chrono::nanoseconds d = tp.time_since_epoch();
Chris@16 337 timespec ts = boost::detail::to_timespec(d);
Chris@16 338 return do_try_lock_until(ts);
Chris@16 339 }
Chris@16 340 #endif
Chris@16 341
Chris@16 342 #define BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE
Chris@16 343 typedef pthread_mutex_t* native_handle_type;
Chris@16 344 native_handle_type native_handle()
Chris@16 345 {
Chris@16 346 return &m;
Chris@16 347 }
Chris@16 348
Chris@16 349 #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
Chris@16 350 typedef unique_lock<timed_mutex> scoped_timed_lock;
Chris@16 351 typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
Chris@16 352 typedef scoped_timed_lock scoped_lock;
Chris@16 353 #endif
Chris@16 354 };
Chris@16 355
Chris@16 356 }
Chris@16 357
Chris@16 358 #include <boost/config/abi_suffix.hpp>
Chris@16 359
Chris@16 360
Chris@16 361 #endif