Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/thread/src/mutex.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 9.9 KB
Line 
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#include <boost/thread/detail/config.hpp>
8
9#include <boost/thread/mutex.hpp>
10#include <boost/thread/xtime.hpp>
11#include <boost/thread/thread.hpp>
12#include <boost/thread/exceptions.hpp>
13#include <boost/limits.hpp>
14#include <string>
15#include <stdexcept>
16#include <cassert>
17#include "timeconv.inl"
18
19#if defined(BOOST_HAS_WINTHREADS)
20#   include <new>
21#   include <boost/thread/once.hpp>
22#   include <windows.h>
23#   include <time.h>
24#   include "mutex.inl"
25#elif defined(BOOST_HAS_PTHREADS)
26#   include <errno.h>
27#elif defined(BOOST_HAS_MPTASKS)
28#    include <MacErrors.h>
29#    include "mac/init.hpp"
30#    include "mac/safe.hpp"
31#endif
32
33namespace boost {
34
35#if defined(BOOST_HAS_WINTHREADS)
36
37mutex::mutex()
38    : m_mutex(0)
39    , m_critical_section(false)
40{
41    m_critical_section = true;
42    if (m_critical_section)
43        m_mutex = new_critical_section();
44    else
45        m_mutex = new_mutex(0);
46}
47
48mutex::~mutex()
49{
50    if (m_critical_section)
51        delete_critical_section(m_mutex);
52    else
53        delete_mutex(m_mutex);
54}
55
56void mutex::do_lock()
57{
58    if (m_critical_section)
59        wait_critical_section_infinite(m_mutex);
60    else
61        wait_mutex(m_mutex, INFINITE);
62}
63
64void mutex::do_unlock()
65{
66    if (m_critical_section)
67        release_critical_section(m_mutex);
68    else
69        release_mutex(m_mutex);
70}
71
72void mutex::do_lock(cv_state&)
73{
74    do_lock();
75}
76
77void mutex::do_unlock(cv_state&)
78{
79    do_unlock();
80}
81
82try_mutex::try_mutex()
83    : m_mutex(0)
84    , m_critical_section(false)
85{
86    m_critical_section = has_TryEnterCriticalSection();
87    if (m_critical_section)
88        m_mutex = new_critical_section();
89    else
90        m_mutex = new_mutex(0);
91}
92
93try_mutex::~try_mutex()
94{
95    if (m_critical_section)
96        delete_critical_section(m_mutex);
97    else
98        delete_mutex(m_mutex);
99}
100
101void try_mutex::do_lock()
102{
103    if (m_critical_section)
104        wait_critical_section_infinite(m_mutex);
105    else
106        wait_mutex(m_mutex, INFINITE);
107}
108
109bool try_mutex::do_trylock()
110{
111    if (m_critical_section)
112        return wait_critical_section_try(m_mutex);
113    else
114        return wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
115}
116
117void try_mutex::do_unlock()
118{
119    if (m_critical_section)
120        release_critical_section(m_mutex);
121    else
122        release_mutex(m_mutex);
123}
124
125void try_mutex::do_lock(cv_state&)
126{
127    do_lock();
128}
129
130void try_mutex::do_unlock(cv_state&)
131{
132    do_unlock();
133}
134
135timed_mutex::timed_mutex()
136    : m_mutex(0)
137{
138    m_mutex = new_mutex(0);
139}
140
141timed_mutex::~timed_mutex()
142{
143    delete_mutex(m_mutex);
144}
145
146void timed_mutex::do_lock()
147{
148    wait_mutex(m_mutex, INFINITE);
149}
150
151bool timed_mutex::do_trylock()
152{
153    return wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
154}
155
156bool timed_mutex::do_timedlock(const xtime& xt)
157{
158    for (;;)
159    {
160        int milliseconds;
161        to_duration(xt, milliseconds);
162
163        int res = wait_mutex(m_mutex, milliseconds);
164
165        if (res == WAIT_TIMEOUT)
166        {
167            boost::xtime cur;
168            boost::xtime_get(&cur, boost::TIME_UTC);
169            if (boost::xtime_cmp(xt, cur) > 0)
170                continue;
171        }
172
173        return res == WAIT_OBJECT_0;
174    }
175}
176
177void timed_mutex::do_unlock()
178{
179    release_mutex(m_mutex);
180}
181
182void timed_mutex::do_lock(cv_state&)
183{
184    do_lock();
185}
186
187void timed_mutex::do_unlock(cv_state&)
188{
189    do_unlock();
190}
191
192#elif defined(BOOST_HAS_PTHREADS)
193
194mutex::mutex()
195{
196    int res = 0;
197    res = pthread_mutex_init(&m_mutex, 0);
198    if (res != 0)
199        throw thread_resource_error();
200}
201
202mutex::~mutex()
203{
204    int res = 0;
205    res = pthread_mutex_destroy(&m_mutex);
206    assert(res == 0);
207}
208
209void mutex::do_lock()
210{
211    int res = 0;
212    res = pthread_mutex_lock(&m_mutex);
213    if (res == EDEADLK) throw lock_error();
214    assert(res == 0);
215}
216
217void mutex::do_unlock()
218{
219    int res = 0;
220    res = pthread_mutex_unlock(&m_mutex);
221    if (res == EPERM) throw lock_error();
222    assert(res == 0);
223}
224
225void mutex::do_lock(cv_state&)
226{
227}
228
229void mutex::do_unlock(cv_state& state)
230{
231    state.pmutex = &m_mutex;
232}
233
234try_mutex::try_mutex()
235{
236    int res = 0;
237    res = pthread_mutex_init(&m_mutex, 0);
238    if (res != 0)
239        throw thread_resource_error();
240}
241
242try_mutex::~try_mutex()
243{
244    int res = 0;
245    res = pthread_mutex_destroy(&m_mutex);
246    assert(res == 0);
247}
248
249void try_mutex::do_lock()
250{
251    int res = 0;
252    res = pthread_mutex_lock(&m_mutex);
253    if (res == EDEADLK) throw lock_error();
254    assert(res == 0);
255}
256
257bool try_mutex::do_trylock()
258{
259    int res = 0;
260    res = pthread_mutex_trylock(&m_mutex);
261    if (res == EDEADLK) throw lock_error();
262    assert(res == 0 || res == EBUSY);
263    return res == 0;
264}
265
266void try_mutex::do_unlock()
267{
268    int res = 0;
269    res = pthread_mutex_unlock(&m_mutex);
270    if (res == EPERM) throw lock_error();
271    assert(res == 0);
272}
273
274void try_mutex::do_lock(cv_state&)
275{
276}
277
278void try_mutex::do_unlock(cv_state& state)
279{
280    state.pmutex = &m_mutex;
281}
282
283timed_mutex::timed_mutex()
284    : m_locked(false)
285{
286    int res = 0;
287    res = pthread_mutex_init(&m_mutex, 0);
288    if (res != 0)
289        throw thread_resource_error();
290
291    res = pthread_cond_init(&m_condition, 0);
292    if (res != 0)
293    {
294        pthread_mutex_destroy(&m_mutex);
295        throw thread_resource_error();
296    }
297}
298
299timed_mutex::~timed_mutex()
300{
301    assert(!m_locked);
302    int res = 0;
303    res = pthread_mutex_destroy(&m_mutex);
304    assert(res == 0);
305
306    res = pthread_cond_destroy(&m_condition);
307    assert(res == 0);
308}
309
310void timed_mutex::do_lock()
311{
312    int res = 0;
313    res = pthread_mutex_lock(&m_mutex);
314    assert(res == 0);
315
316    while (m_locked)
317    {
318        res = pthread_cond_wait(&m_condition, &m_mutex);
319        assert(res == 0);
320    }
321
322    assert(!m_locked);
323    m_locked = true;
324
325    res = pthread_mutex_unlock(&m_mutex);
326    assert(res == 0);
327}
328
329bool timed_mutex::do_trylock()
330{
331    int res = 0;
332    res = pthread_mutex_lock(&m_mutex);
333    assert(res == 0);
334
335    bool ret = false;
336    if (!m_locked)
337    {
338        m_locked = true;
339        ret = true;
340    }
341
342    res = pthread_mutex_unlock(&m_mutex);
343    assert(res == 0);
344    return ret;
345}
346
347bool timed_mutex::do_timedlock(const xtime& xt)
348{
349    int res = 0;
350    res = pthread_mutex_lock(&m_mutex);
351    assert(res == 0);
352
353    timespec ts;
354    to_timespec(xt, ts);
355
356    while (m_locked)
357    {
358        res = pthread_cond_timedwait(&m_condition, &m_mutex, &ts);
359        assert(res == 0 || res == ETIMEDOUT);
360
361        if (res == ETIMEDOUT)
362            break;
363    }
364
365    bool ret = false;
366    if (!m_locked)
367    {
368        m_locked = true;
369        ret = true;
370    }
371
372    res = pthread_mutex_unlock(&m_mutex);
373    assert(res == 0);
374    return ret;
375}
376
377void timed_mutex::do_unlock()
378{
379    int res = 0;
380    res = pthread_mutex_lock(&m_mutex);
381    assert(res == 0);
382
383    assert(m_locked);
384    m_locked = false;
385
386    res = pthread_cond_signal(&m_condition);
387    assert(res == 0);
388
389    res = pthread_mutex_unlock(&m_mutex);
390    assert(res == 0);
391}
392
393void timed_mutex::do_lock(cv_state&)
394{
395    int res = 0;
396    while (m_locked)
397    {
398        res = pthread_cond_wait(&m_condition, &m_mutex);
399        assert(res == 0);
400    }
401
402    assert(!m_locked);
403    m_locked = true;
404
405    res = pthread_mutex_unlock(&m_mutex);
406    assert(res == 0);
407}
408
409void timed_mutex::do_unlock(cv_state& state)
410{
411    int res = 0;
412    res = pthread_mutex_lock(&m_mutex);
413    assert(res == 0);
414
415    assert(m_locked);
416    m_locked = false;
417
418    res = pthread_cond_signal(&m_condition);
419    assert(res == 0);
420
421    state.pmutex = &m_mutex;
422}
423
424#elif defined(BOOST_HAS_MPTASKS)
425
426using threads::mac::detail::safe_enter_critical_region;
427
428mutex::mutex()
429{
430}
431
432mutex::~mutex()
433{
434}
435
436void mutex::do_lock()
437{
438    OSStatus lStatus = noErr;
439    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
440        m_mutex_mutex);
441    assert(lStatus == noErr);
442}
443
444void mutex::do_unlock()
445{
446    OSStatus lStatus = noErr;
447    lStatus = MPExitCriticalRegion(m_mutex);
448    assert(lStatus == noErr);
449}
450
451void mutex::do_lock(cv_state& /*state*/)
452{
453    do_lock();
454}
455
456void mutex::do_unlock(cv_state& /*state*/)
457{
458    do_unlock();
459}
460
461try_mutex::try_mutex()
462{
463}
464
465try_mutex::~try_mutex()
466{
467}
468
469void try_mutex::do_lock()
470{
471    OSStatus lStatus = noErr;
472    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
473        m_mutex_mutex);
474    assert(lStatus == noErr);
475}
476
477bool try_mutex::do_trylock()
478{
479    OSStatus lStatus = noErr;
480    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
481    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
482    return lStatus == noErr;
483}
484
485void try_mutex::do_unlock()
486{
487    OSStatus lStatus = noErr;
488    lStatus = MPExitCriticalRegion(m_mutex);
489    assert(lStatus == noErr);
490}
491
492void try_mutex::do_lock(cv_state& /*state*/)
493{
494    do_lock();
495}
496
497void try_mutex::do_unlock(cv_state& /*state*/)
498{
499    do_unlock();
500}
501
502timed_mutex::timed_mutex()
503{
504}
505
506timed_mutex::~timed_mutex()
507{
508}
509
510void timed_mutex::do_lock()
511{
512    OSStatus lStatus = noErr;
513    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
514        m_mutex_mutex);
515    assert(lStatus == noErr);
516}
517
518bool timed_mutex::do_trylock()
519{
520    OSStatus lStatus = noErr;
521    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
522    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
523    return(lStatus == noErr);
524}
525
526bool timed_mutex::do_timedlock(const xtime& xt)
527{
528    int microseconds;
529    to_microduration(xt, microseconds);
530    Duration lDuration = kDurationMicrosecond * microseconds;
531
532    OSStatus lStatus = noErr;
533    lStatus = safe_enter_critical_region(m_mutex, lDuration, m_mutex_mutex);
534    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
535
536    return(lStatus == noErr);
537}
538
539void timed_mutex::do_unlock()
540{
541    OSStatus lStatus = noErr;
542    lStatus = MPExitCriticalRegion(m_mutex);
543    assert(lStatus == noErr);
544}
545
546void timed_mutex::do_lock(cv_state& /*state*/)
547{
548    do_lock();
549}
550
551void timed_mutex::do_unlock(cv_state& /*state*/)
552{
553    do_unlock();
554}
555
556#endif
557
558} // namespace boost
559
560// Change Log:
561//   8 Feb 01  WEKEMPF Initial version.
Note: See TracBrowser for help on using the repository browser.