source: NonGTP/Boost/boost/thread/detail/lock.hpp @ 857

Revision 857, 5.0 KB checked in by igarcia, 18 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_XLOCK_WEK070601_HPP
13#define BOOST_XLOCK_WEK070601_HPP
14
15#include <boost/thread/detail/config.hpp>
16
17#include <boost/utility.hpp>
18#include <boost/thread/exceptions.hpp>
19
20namespace boost {
21
22class condition;
23struct xtime;
24
25namespace detail { namespace thread {
26
27template <typename Mutex>
28class lock_ops : private noncopyable
29{
30private:
31    lock_ops() { }
32
33public:
34    typedef typename Mutex::cv_state lock_state;
35
36    static void lock(Mutex& m)
37    {
38        m.do_lock();
39    }
40    static bool trylock(Mutex& m)
41    {
42        return m.do_trylock();
43    }
44    static bool timedlock(Mutex& m, const xtime& xt)
45    {
46        return m.do_timedlock(xt);
47    }
48    static void unlock(Mutex& m)
49    {
50        m.do_unlock();
51    }
52    static void lock(Mutex& m, lock_state& state)
53    {
54        m.do_lock(state);
55    }
56    static void unlock(Mutex& m, lock_state& state)
57    {
58        m.do_unlock(state);
59    }
60};
61
62template <typename Mutex>
63class scoped_lock : private noncopyable
64{
65public:
66    typedef Mutex mutex_type;
67
68    explicit scoped_lock(Mutex& mx, bool initially_locked=true)
69        : m_mutex(mx), m_locked(false)
70    {
71        if (initially_locked) lock();
72    }
73    ~scoped_lock()
74    {
75        if (m_locked) unlock();
76    }
77
78    void lock()
79    {
80        if (m_locked) throw lock_error();
81        lock_ops<Mutex>::lock(m_mutex);
82        m_locked = true;
83    }
84    void unlock()
85    {
86        if (!m_locked) throw lock_error();
87        lock_ops<Mutex>::unlock(m_mutex);
88        m_locked = false;
89    }
90
91    bool locked() const { return m_locked; }
92    operator const void*() const { return m_locked ? this : 0; }
93
94private:
95    friend class boost::condition;
96
97    Mutex& m_mutex;
98    bool m_locked;
99};
100
101template <typename TryMutex>
102class scoped_try_lock : private noncopyable
103{
104public:
105    typedef TryMutex mutex_type;
106
107    explicit scoped_try_lock(TryMutex& mx)
108        : m_mutex(mx), m_locked(false)
109    {
110        try_lock();
111    }
112    scoped_try_lock(TryMutex& mx, bool initially_locked)
113        : m_mutex(mx), m_locked(false)
114    {
115        if (initially_locked) lock();
116    }
117    ~scoped_try_lock()
118    {
119        if (m_locked) unlock();
120    }
121
122    void lock()
123    {
124        if (m_locked) throw lock_error();
125        lock_ops<TryMutex>::lock(m_mutex);
126        m_locked = true;
127    }
128    bool try_lock()
129    {
130        if (m_locked) throw lock_error();
131        return (m_locked = lock_ops<TryMutex>::trylock(m_mutex));
132    }
133    void unlock()
134    {
135        if (!m_locked) throw lock_error();
136        lock_ops<TryMutex>::unlock(m_mutex);
137        m_locked = false;
138    }
139
140    bool locked() const { return m_locked; }
141    operator const void*() const { return m_locked ? this : 0; }
142
143private:
144    friend class boost::condition;
145
146    TryMutex& m_mutex;
147    bool m_locked;
148};
149
150template <typename TimedMutex>
151class scoped_timed_lock : private noncopyable
152{
153public:
154    typedef TimedMutex mutex_type;
155
156    scoped_timed_lock(TimedMutex& mx, const xtime& xt)
157        : m_mutex(mx), m_locked(false)
158    {
159        timed_lock(xt);
160    }
161    scoped_timed_lock(TimedMutex& mx, bool initially_locked)
162        : m_mutex(mx), m_locked(false)
163    {
164        if (initially_locked) lock();
165    }
166    ~scoped_timed_lock()
167    {
168        if (m_locked) unlock();
169    }
170
171    void lock()
172    {
173        if (m_locked) throw lock_error();
174        lock_ops<TimedMutex>::lock(m_mutex);
175        m_locked = true;
176    }
177    bool try_lock()
178    {
179        if (m_locked) throw lock_error();
180        return (m_locked = lock_ops<TimedMutex>::trylock(m_mutex));
181    }
182    bool timed_lock(const xtime& xt)
183    {
184        if (m_locked) throw lock_error();
185        return (m_locked = lock_ops<TimedMutex>::timedlock(m_mutex, xt));
186    }
187    void unlock()
188    {
189        if (!m_locked) throw lock_error();
190        lock_ops<TimedMutex>::unlock(m_mutex);
191        m_locked = false;
192    }
193
194    bool locked() const { return m_locked; }
195    operator const void*() const { return m_locked ? this : 0; }
196
197private:
198    friend class boost::condition;
199
200    TimedMutex& m_mutex;
201    bool m_locked;
202};
203
204} // namespace thread
205} // namespace detail
206} // namespace boost
207
208#endif // BOOST_XLOCK_WEK070601_HPP
209
210// Change Log:
211//    8 Feb 01  WEKEMPF Initial version.
212//   22 May 01  WEKEMPF Modified to use xtime for time outs.
213//   30 Jul 01  WEKEMPF Moved lock types into boost::detail::thread. Renamed
214//                      some types. Added locked() methods.
Note: See TracBrowser for help on using the repository browser.