os/ossrv/ossrv_pub/boost_apis/boost/thread/condition.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (C) 2001-2003
     2 // William E. Kempf
     3 //
     4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
     5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     6 
     7 #ifndef BOOST_CONDITION_WEK070601_HPP
     8 #define BOOST_CONDITION_WEK070601_HPP
     9 
    10 #include <boost/thread/detail/config.hpp>
    11 
    12 #include <boost/thread/exceptions.hpp>
    13 #include <boost/utility.hpp>
    14 #include <boost/thread/detail/lock.hpp>
    15 
    16 #if defined(BOOST_HAS_PTHREADS)
    17 #   include <pthread.h>
    18 #elif defined(BOOST_HAS_MPTASKS)
    19 #   include "scoped_critical_region.hpp"
    20 #endif
    21 
    22 namespace boost {
    23 
    24 struct xtime;
    25 // disable warnings about non dll import
    26 // see: http://www.boost.org/more/separate_compilation.html#dlls
    27 #ifdef BOOST_MSVC
    28 #   pragma warning(push)
    29 #   pragma warning(disable: 4251 4231 4660 4275)
    30 #endif
    31 
    32 namespace detail {
    33 
    34 class BOOST_THREAD_DECL condition_impl : private noncopyable
    35 {
    36     friend class condition;
    37 
    38 public:
    39     condition_impl();
    40     ~condition_impl();
    41 
    42     void notify_one();
    43     void notify_all();
    44 
    45 #if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
    46     void enter_wait();
    47     void do_wait();
    48     bool do_timed_wait(const xtime& xt);
    49 #elif defined(BOOST_HAS_PTHREADS)
    50     void do_wait(pthread_mutex_t* pmutex);
    51     bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
    52 #endif
    53 
    54 #if defined(BOOST_HAS_WINTHREADS)
    55     void* m_gate;
    56     void* m_queue;
    57     void* m_mutex;
    58     unsigned m_gone;  // # threads that timed out and never made it to m_queue
    59     unsigned long m_blocked; // # threads blocked on the condition
    60     unsigned m_waiting; // # threads no longer waiting for the condition but
    61                         // still waiting to be removed from m_queue
    62 #elif defined(BOOST_HAS_PTHREADS)
    63     pthread_cond_t m_condition;
    64 #elif defined(BOOST_HAS_MPTASKS)
    65     MPSemaphoreID m_gate;
    66     MPSemaphoreID m_queue;
    67     threads::mac::detail::scoped_critical_region m_mutex;
    68     threads::mac::detail::scoped_critical_region m_mutex_mutex;
    69     unsigned m_gone; // # threads that timed out and never made it to m_queue
    70     unsigned long m_blocked; // # threads blocked on the condition
    71     unsigned m_waiting; // # threads no longer waiting for the condition but
    72                         // still waiting to be removed from m_queue
    73 #endif
    74 };
    75 
    76 } // namespace detail
    77 
    78 class condition : private noncopyable
    79 {
    80 public:
    81     condition() { }
    82     ~condition() { }
    83 
    84     void notify_one() { m_impl.notify_one(); }
    85     void notify_all() { m_impl.notify_all(); }
    86 
    87     template <typename L>
    88     void wait(L& lock)
    89     {
    90         if (!lock)
    91             throw lock_error();
    92 
    93         do_wait(lock.m_mutex);
    94     }
    95 
    96     template <typename L, typename Pr>
    97     void wait(L& lock, Pr pred)
    98     {
    99         if (!lock)
   100             throw lock_error();
   101 
   102         while (!pred())
   103             do_wait(lock.m_mutex);
   104     }
   105 
   106     template <typename L>
   107     bool timed_wait(L& lock, const xtime& xt)
   108     {
   109         if (!lock)
   110             throw lock_error();
   111 
   112         return do_timed_wait(lock.m_mutex, xt);
   113     }
   114 
   115     template <typename L, typename Pr>
   116     bool timed_wait(L& lock, const xtime& xt, Pr pred)
   117     {
   118         if (!lock)
   119             throw lock_error();
   120 
   121         while (!pred())
   122         {
   123             if (!do_timed_wait(lock.m_mutex, xt))
   124                 return false;
   125         }
   126 
   127         return true;
   128     }
   129 
   130 private:
   131     detail::condition_impl m_impl;
   132 
   133     template <typename M>
   134     void do_wait(M& mutex)
   135     {
   136 #if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
   137         m_impl.enter_wait();
   138 #endif
   139 
   140         typedef detail::thread::lock_ops<M>
   141 #if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
   142 # define lock_ops lock_ops_  // HP confuses lock_ops witht the template
   143 #endif
   144             lock_ops;
   145 
   146         typename lock_ops::lock_state state;
   147         lock_ops::unlock(mutex, state);
   148 
   149 #if defined(BOOST_HAS_PTHREADS)
   150         m_impl.do_wait(state.pmutex);
   151 #elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
   152         m_impl.do_wait();
   153 #endif
   154 
   155         lock_ops::lock(mutex, state);
   156 #undef lock_ops
   157     }
   158 
   159     template <typename M>
   160     bool do_timed_wait(M& mutex, const xtime& xt)
   161     {
   162 #if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
   163         m_impl.enter_wait();
   164 #endif
   165 
   166         typedef detail::thread::lock_ops<M>
   167 #if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
   168 # define lock_ops lock_ops_  // HP confuses lock_ops witht the template
   169 #endif
   170             lock_ops;
   171 
   172         typename lock_ops::lock_state state;
   173         lock_ops::unlock(mutex, state);
   174 
   175         bool ret = false;
   176 
   177 #if defined(BOOST_HAS_PTHREADS)
   178         ret = m_impl.do_timed_wait(xt, state.pmutex);
   179 #elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
   180         ret = m_impl.do_timed_wait(xt);
   181 #endif
   182 
   183         lock_ops::lock(mutex, state);
   184 #undef lock_ops
   185 
   186         return ret;
   187     }
   188 };
   189 #ifdef BOOST_MSVC
   190 #   pragma warning(pop)
   191 #endif
   192 } // namespace boost
   193 
   194 // Change Log:
   195 //    8 Feb 01  WEKEMPF Initial version.
   196 //   22 May 01  WEKEMPF Modified to use xtime for time outs.
   197 //   23 May 01  WEKEMPF Removed "duration" timed_waits, as they are too
   198 //                      difficult to use with spurious wakeups.
   199 //    3 Jan 03  WEKEMPF Modified for DLL implementation.
   200 
   201 #endif // BOOST_CONDITION_WEK070601_HPP