/storage/packages/boost/1.61_gcc-5.3/include/boost/thread/pthread/mutex.hpp

Line% of fetchesSource
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  
          ret = ::pthread_mutex_destroy(m);
54  
      } 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  
          ret = ::pthread_mutex_lock(m);
63  
      } 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  
          ret = ::pthread_mutex_unlock(m);
72  
      } 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  
        mutex()
100  
        {
101  
            int const res=pthread_mutex_init(&m,NULL);
102  
            if(res)
103  
            {
104  
                boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
105  
            }
106  
        }
107  
        ~mutex()
108  
        {
109  
          int const res = posix::pthread_mutex_destroy(&m);
110  
          boost::ignore_unused(res);
111  
          BOOST_ASSERT(!res);
112  
        }
113  
114  
        void lock()
115  
        {
116  
            int res = posix::pthread_mutex_lock(&m);
117  
            if (res)
118  
            {
119  
                boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
120  
            }
121  
        }
122  
123  
        void unlock()
124  
        {
125  
            int res = posix::pthread_mutex_unlock(&m);
126  
            (void)res;
127  
            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  
        }
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
362  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.