source: NonGTP/Boost/boost/thread/condition.hpp @ 857

Revision 857, 5.4 KB checked in by igarcia, 19 years ago (diff)
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4// Permission to use, copy, modify, distribute and sell this software
5// and its documentation for any purpose is hereby granted without fee,
6// provided that the above copyright notice appear in all copies and
7// that both that copyright notice and this permission notice appear
8// in supporting documentation.  William E. Kempf makes no representations
9// about the suitability of this software for any purpose.
10// It is provided "as is" without express or implied warranty.
11
12#ifndef BOOST_CONDITION_WEK070601_HPP
13#define BOOST_CONDITION_WEK070601_HPP
14
15#include <boost/thread/detail/config.hpp>
16
17#include <boost/thread/exceptions.hpp>
18#include <boost/utility.hpp>
19#include <boost/thread/detail/lock.hpp>
20
21#if defined(BOOST_HAS_PTHREADS)
22#   include <pthread.h>
23#elif defined(BOOST_HAS_MPTASKS)
24#   include "scoped_critical_region.hpp"
25#endif
26
27namespace boost {
28
29struct xtime;
30
31namespace detail {
32
33class BOOST_THREAD_DECL condition_impl : private noncopyable
34{
35    friend class condition;
36
37public:
38    condition_impl();
39    ~condition_impl();
40
41    void notify_one();
42    void notify_all();
43
44#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
45    void enter_wait();
46    void do_wait();
47    bool do_timed_wait(const xtime& xt);
48#elif defined(BOOST_HAS_PTHREADS)
49    void do_wait(pthread_mutex_t* pmutex);
50    bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
51#endif
52
53#if defined(BOOST_HAS_WINTHREADS)
54    void* m_gate;
55    void* m_queue;
56    void* m_mutex;
57    unsigned m_gone;  // # threads that timed out and never made it to m_queue
58    unsigned long m_blocked; // # threads blocked on the condition
59    unsigned m_waiting; // # threads no longer waiting for the condition but
60                        // still waiting to be removed from m_queue
61#elif defined(BOOST_HAS_PTHREADS)
62    pthread_cond_t m_condition;
63#elif defined(BOOST_HAS_MPTASKS)
64    MPSemaphoreID m_gate;
65    MPSemaphoreID m_queue;
66    threads::mac::detail::scoped_critical_region m_mutex;
67    threads::mac::detail::scoped_critical_region m_mutex_mutex;
68    unsigned m_gone; // # threads that timed out and never made it to m_queue
69    unsigned long m_blocked; // # threads blocked on the condition
70    unsigned m_waiting; // # threads no longer waiting for the condition but
71                        // still waiting to be removed from m_queue
72#endif
73};
74
75} // namespace detail
76
77class condition : private noncopyable
78{
79public:
80    condition() { }
81    ~condition() { }
82
83    void notify_one() { m_impl.notify_one(); }
84    void notify_all() { m_impl.notify_all(); }
85
86    template <typename L>
87    void wait(L& lock)
88    {
89        if (!lock)
90            throw lock_error();
91
92        do_wait(lock.m_mutex);
93    }
94
95    template <typename L, typename Pr>
96    void wait(L& lock, Pr pred)
97    {
98        if (!lock)
99            throw lock_error();
100
101        while (!pred())
102            do_wait(lock.m_mutex);
103    }
104
105    template <typename L>
106    bool timed_wait(L& lock, const xtime& xt)
107    {
108        if (!lock)
109            throw lock_error();
110
111        return do_timed_wait(lock.m_mutex, xt);
112    }
113
114    template <typename L, typename Pr>
115    bool timed_wait(L& lock, const xtime& xt, Pr pred)
116    {
117        if (!lock)
118            throw lock_error();
119
120        while (!pred())
121        {
122            if (!do_timed_wait(lock.m_mutex, xt))
123                return false;
124        }
125
126        return true;
127    }
128
129private:
130    detail::condition_impl m_impl;
131
132    template <typename M>
133    void do_wait(M& mutex)
134    {
135#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
136        m_impl.enter_wait();
137#endif
138
139        typedef detail::thread::lock_ops<M>
140#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
141# define lock_ops lock_ops_  // HP confuses lock_ops witht the template
142#endif
143            lock_ops;
144
145        typename lock_ops::lock_state state;
146        lock_ops::unlock(mutex, state);
147
148#if defined(BOOST_HAS_PTHREADS)
149        m_impl.do_wait(state.pmutex);
150#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
151        m_impl.do_wait();
152#endif
153
154        lock_ops::lock(mutex, state);
155#undef lock_ops
156    }
157
158    template <typename M>
159    bool do_timed_wait(M& mutex, const xtime& xt)
160    {
161#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
162        m_impl.enter_wait();
163#endif
164
165        typedef detail::thread::lock_ops<M>
166#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
167# define lock_ops lock_ops_  // HP confuses lock_ops witht the template
168#endif
169            lock_ops;
170
171        typename lock_ops::lock_state state;
172        lock_ops::unlock(mutex, state);
173
174        bool ret = false;
175
176#if defined(BOOST_HAS_PTHREADS)
177        ret = m_impl.do_timed_wait(xt, state.pmutex);
178#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
179        ret = m_impl.do_timed_wait(xt);
180#endif
181
182        lock_ops::lock(mutex, state);
183#undef lock_ops
184
185        return ret;
186    }
187};
188
189} // namespace boost
190
191// Change Log:
192//    8 Feb 01  WEKEMPF Initial version.
193//   22 May 01  WEKEMPF Modified to use xtime for time outs.
194//   23 May 01  WEKEMPF Removed "duration" timed_waits, as they are too
195//                      difficult to use with spurious wakeups.
196//    3 Jan 03  WEKEMPF Modified for DLL implementation.
197
198#endif // BOOST_CONDITION_WEK070601_HPP
Note: See TracBrowser for help on using the repository browser.