ossrv_pub/boost_apis/boost/thread/condition.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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