LCOV - code coverage report
Current view: top level - usr/include/boost/thread/pthread - mutex.hpp (source / functions) Hit Total Coverage
Test: bitcoincash_test.info Lines: 23 25 92.0 %
Date: 2018-04-13 15:12:50 Functions: 4 4 100.0 %

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

Generated by: LCOV version 1.12