Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / thread / pthread / mutex.hpp
index 2c5af92..3e9af2a 100644 (file)
@@ -6,10 +6,14 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
+#include <boost/thread/detail/config.hpp>
 #include <pthread.h>
 #include <boost/throw_exception.hpp>
+#include <boost/core/ignore_unused.hpp>
 #include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
 #include <boost/thread/thread_time.hpp>
 #include <boost/thread/xtime.hpp>
 #include <boost/assert.hpp>
 #include <boost/thread/detail/delete.hpp>
 
 #ifdef _POSIX_TIMEOUTS
-#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L
+#if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
 #define BOOST_PTHREAD_HAS_TIMEDLOCK
 #endif
 #endif
+#endif
+
 
 #include <boost/config/abi_prefix.hpp>
 
+#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
+#define BOOST_THREAD_HAS_EINTR_BUG
+#endif
+
 namespace boost
 {
+  namespace posix {
+#ifdef BOOST_THREAD_HAS_EINTR_BUG
+    BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+    {
+      int ret;
+      do
+      {
+          ret = ::pthread_mutex_destroy(m);
+      } while (ret == EINTR);
+      return ret;
+    }
+    BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+    {
+      int ret;
+      do
+      {
+          ret = ::pthread_mutex_lock(m);
+      } while (ret == EINTR);
+      return ret;
+    }
+    BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+    {
+      int ret;
+      do
+      {
+          ret = ::pthread_mutex_unlock(m);
+      } while (ret == EINTR);
+      return ret;
+    }
+#else
+    BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+    {
+      return ::pthread_mutex_destroy(m);
+    }
+    BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+    {
+      return ::pthread_mutex_lock(m);
+    }
+    BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+    {
+      return ::pthread_mutex_unlock(m);
+    }
+
+#endif
+
+  }
     class mutex
     {
     private:
@@ -49,20 +106,14 @@ namespace boost
         }
         ~mutex()
         {
-            int ret;
-            do
-            {
-                ret = pthread_mutex_destroy(&m);
-            } while (ret == EINTR);
+          int const res = posix::pthread_mutex_destroy(&m);
+          boost::ignore_unused(res);
+          BOOST_ASSERT(!res);
         }
 
         void lock()
         {
-            int res;
-            do
-            {
-                res = pthread_mutex_lock(&m);
-            } while (res == EINTR);
+            int res = posix::pthread_mutex_lock(&m);
             if (res)
             {
                 boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
@@ -71,12 +122,11 @@ namespace boost
 
         void unlock()
         {
-            int ret;
-            do
+            int res = posix::pthread_mutex_unlock(&m);
+            if (res)
             {
-                ret = pthread_mutex_unlock(&m);
-            } while (ret == EINTR);
-            BOOST_VERIFY(!ret);
+                boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+            }
         }
 
         bool try_lock()
@@ -86,12 +136,8 @@ namespace boost
             {
                 res = pthread_mutex_trylock(&m);
             } while (res == EINTR);
-            if(res && (res!=EBUSY))
+            if (res==EBUSY)
             {
-                // The following throw_exception has been replaced by an assertion and just return false,
-                // as this is an internal error and the user can do nothing with the exception.
-                //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock"));
-                BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock");
                 return false;
             }
 
@@ -105,8 +151,10 @@ namespace boost
             return &m;
         }
 
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
         typedef unique_lock<mutex> scoped_lock;
         typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+#endif
     };
 
     typedef mutex try_mutex;
@@ -132,7 +180,8 @@ namespace boost
             int const res2=pthread_cond_init(&cond,NULL);
             if(res2)
             {
-                BOOST_VERIFY(!pthread_mutex_destroy(&m));
+                BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
+                //BOOST_VERIFY(!pthread_mutex_destroy(&m));
                 boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
             }
             is_locked=false;
@@ -140,12 +189,13 @@ namespace boost
         }
         ~timed_mutex()
         {
-            BOOST_VERIFY(!pthread_mutex_destroy(&m));
+            BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
             BOOST_VERIFY(!pthread_cond_destroy(&cond));
 #endif
         }
 
+#if defined BOOST_THREAD_USES_DATETIME
         template<typename TimeDuration>
         bool timed_lock(TimeDuration const & relative_time)
         {
@@ -155,23 +205,39 @@ namespace boost
         {
             return timed_lock(system_time(absolute_time));
         }
-
+#endif
 #ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
         void lock()
         {
-            BOOST_VERIFY(!pthread_mutex_lock(&m));
+            int res = posix::pthread_mutex_lock(&m);
+            if (res)
+            {
+                boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
+            }
         }
 
         void unlock()
         {
-            BOOST_VERIFY(!pthread_mutex_unlock(&m));
+            int res = posix::pthread_mutex_unlock(&m);
+            if (res)
+            {
+                boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+            }
         }
 
         bool try_lock()
         {
-            int const res=pthread_mutex_trylock(&m);
-            BOOST_ASSERT(!res || res==EBUSY);
-            return !res;
+          int res;
+          do
+          {
+              res = pthread_mutex_trylock(&m);
+          } while (res == EINTR);
+          if (res==EBUSY)
+          {
+              return false;
+          }
+
+          return !res;
         }
 
 
@@ -232,12 +298,13 @@ namespace boost
     public:
 #endif
 
+#if defined BOOST_THREAD_USES_DATETIME
         bool timed_lock(system_time const & abs_time)
         {
-            struct timespec const ts=detail::get_timespec(abs_time);
+            struct timespec const ts=boost::detail::to_timespec(abs_time);
             return do_try_lock_until(ts);
         }
-
+#endif
 #ifdef BOOST_THREAD_USES_CHRONO
         template <class Rep, class Period>
         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
@@ -261,12 +328,9 @@ namespace boost
         }
         bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
         {
-          using namespace chrono;
-          nanoseconds d = tp.time_since_epoch();
-          timespec ts;
-          seconds s = duration_cast<seconds>(d);
-          ts.tv_sec = static_cast<long>(s.count());
-          ts.tv_nsec = static_cast<long>((d - s).count());
+          //using namespace chrono;
+          chrono::nanoseconds d = tp.time_since_epoch();
+          timespec ts = boost::detail::to_timespec(d);
           return do_try_lock_until(ts);
         }
 #endif
@@ -278,9 +342,11 @@ namespace boost
             return &m;
         }
 
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
         typedef unique_lock<timed_mutex> scoped_timed_lock;
         typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
+#endif
     };
 
 }