Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/src/recursive_mutex.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 21.3 KB
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#include <boost/thread/detail/config.hpp>
13
14#include <boost/thread/recursive_mutex.hpp>
15#include <boost/thread/xtime.hpp>
16#include <boost/thread/thread.hpp>
17#include <boost/limits.hpp>
18#include <string>
19#include <stdexcept>
20#include <cassert>
21#include "timeconv.inl"
22
23#if defined(BOOST_HAS_WINTHREADS)
24#   include <new>
25#   include <boost/thread/once.hpp>
26#   include <windows.h>
27#   include <time.h>
28#   include "mutex.inl"
29#elif defined(BOOST_HAS_PTHREADS)
30#   include <errno.h>
31#elif defined(BOOST_HAS_MPTASKS)
32#   include <MacErrors.h>
33#   include "safe.hpp"
34#endif
35
36namespace boost {
37
38#if defined(BOOST_HAS_WINTHREADS)
39
40recursive_mutex::recursive_mutex()
41    : m_mutex(0)
42    , m_critical_section(false)
43    , m_count(0)
44{
45    m_critical_section = true;
46    if (m_critical_section)
47        m_mutex = new_critical_section();
48    else
49        m_mutex = new_mutex(0);
50}
51
52recursive_mutex::~recursive_mutex()
53{
54    if (m_critical_section)
55        delete_critical_section(m_mutex);
56    else
57        delete_mutex(m_mutex);
58}
59
60void recursive_mutex::do_lock()
61{
62    if (m_critical_section)
63        wait_critical_section_infinite(m_mutex);
64    else
65        wait_mutex(m_mutex, INFINITE);
66
67    if (++m_count > 1)
68    {
69        if (m_critical_section)
70            release_critical_section(m_mutex);
71        else
72            release_mutex(m_mutex);
73    }
74}
75
76void recursive_mutex::do_unlock()
77{
78    if (--m_count == 0)
79    {
80        if (m_critical_section)
81            release_critical_section(m_mutex);
82        else
83            release_mutex(m_mutex);
84    }
85}
86
87void recursive_mutex::do_lock(cv_state& state)
88{
89    if (m_critical_section)
90        wait_critical_section_infinite(m_mutex);
91    else
92        wait_mutex(m_mutex, INFINITE);
93
94    m_count = state;
95}
96
97void recursive_mutex::do_unlock(cv_state& state)
98{
99    state = m_count;
100    m_count = 0;
101
102    if (m_critical_section)
103        release_critical_section(m_mutex);
104    else
105        release_mutex(m_mutex);
106}
107
108recursive_try_mutex::recursive_try_mutex()
109    : m_mutex(0)
110    , m_critical_section(false)
111    , m_count(0)
112{
113    m_critical_section = has_TryEnterCriticalSection();
114    if (m_critical_section)
115        m_mutex = new_critical_section();
116    else
117        m_mutex = new_mutex(0);
118}
119
120recursive_try_mutex::~recursive_try_mutex()
121{
122    if (m_critical_section)
123        delete_critical_section(m_mutex);
124    else
125        delete_mutex(m_mutex);
126}
127
128void recursive_try_mutex::do_lock()
129{
130    if (m_critical_section)
131        wait_critical_section_infinite(m_mutex);
132    else
133        wait_mutex(m_mutex, INFINITE);
134
135    if (++m_count > 1)
136    {
137        if (m_critical_section)
138            release_critical_section(m_mutex);
139        else
140            release_mutex(m_mutex);
141    }
142}
143
144bool recursive_try_mutex::do_trylock()
145{
146    bool res = false;
147    if (m_critical_section)
148        res = wait_critical_section_try(m_mutex);
149    else
150        res = wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
151
152    if (res)
153    {
154        if (++m_count > 1)
155        {
156            if (m_critical_section)
157                release_critical_section(m_mutex);
158            else
159                release_mutex(m_mutex);
160        }
161        return true;
162    }
163    return false;
164}
165
166void recursive_try_mutex::do_unlock()
167{
168    if (--m_count == 0)
169    {
170        if (m_critical_section)
171            release_critical_section(m_mutex);
172        else
173            release_mutex(m_mutex);
174    }
175}
176
177void recursive_try_mutex::do_lock(cv_state& state)
178{
179    if (m_critical_section)
180        wait_critical_section_infinite(m_mutex);
181    else
182        wait_mutex(m_mutex, INFINITE);
183
184    m_count = state;
185}
186
187void recursive_try_mutex::do_unlock(cv_state& state)
188{
189    state = m_count;
190    m_count = 0;
191
192    if (m_critical_section)
193        release_critical_section(m_mutex);
194    else
195        release_mutex(m_mutex);
196}
197
198recursive_timed_mutex::recursive_timed_mutex()
199    : m_mutex(0)
200    , m_count(0)
201{
202    m_mutex = new_mutex(0);
203}
204
205recursive_timed_mutex::~recursive_timed_mutex()
206{
207    delete_mutex(m_mutex);
208}
209
210void recursive_timed_mutex::do_lock()
211{
212    wait_mutex(m_mutex, INFINITE);
213
214    if (++m_count > 1)
215        release_mutex(m_mutex);
216}
217
218bool recursive_timed_mutex::do_trylock()
219{
220    bool res = wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
221
222    if (res)
223    {
224        if (++m_count > 1)
225            release_mutex(m_mutex);
226        return true;
227    }
228    return false;
229}
230
231bool recursive_timed_mutex::do_timedlock(const xtime& xt)
232{
233    for (;;)
234    {
235        int milliseconds;
236        to_duration(xt, milliseconds);
237
238        unsigned int res = wait_mutex(m_mutex, milliseconds);
239
240        if (res == WAIT_TIMEOUT)
241        {
242            xtime cur;
243            xtime_get(&cur, TIME_UTC);
244            if (xtime_cmp(xt, cur) > 0)
245                continue;
246        }
247
248        if (res == WAIT_OBJECT_0)
249        {
250            if (++m_count > 1)
251                release_mutex(m_mutex);
252            return true;
253        }
254
255        return false;
256    }
257}
258
259void recursive_timed_mutex::do_unlock()
260{
261    if (--m_count == 0)
262        release_mutex(m_mutex);
263}
264
265void recursive_timed_mutex::do_lock(cv_state& state)
266{
267    wait_mutex(m_mutex, INFINITE);
268
269    m_count = state;
270}
271
272void recursive_timed_mutex::do_unlock(cv_state& state)
273{
274    state = m_count;
275    m_count = 0;
276
277    release_mutex(m_mutex);
278}
279
280#elif defined(BOOST_HAS_PTHREADS)
281
282recursive_mutex::recursive_mutex()
283    : m_count(0)
284#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
285    , m_valid_id(false)
286#   endif
287{
288    pthread_mutexattr_t attr;
289    int res = pthread_mutexattr_init(&attr);
290    assert(res == 0);
291
292#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
293    res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
294    assert(res == 0);
295#   endif
296
297    res = pthread_mutex_init(&m_mutex, &attr);
298    {
299        int res = pthread_mutexattr_destroy(&attr);
300        assert(res == 0);
301    }
302    if (res != 0)
303        throw thread_resource_error();
304
305#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
306    res = pthread_cond_init(&m_unlocked, 0);
307    if (res != 0)
308    {
309        pthread_mutex_destroy(&m_mutex);
310        throw thread_resource_error();
311    }
312#   endif
313}
314
315recursive_mutex::~recursive_mutex()
316{
317    int res = 0;
318    res = pthread_mutex_destroy(&m_mutex);
319    assert(res == 0);
320
321#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
322    res = pthread_cond_destroy(&m_unlocked);
323    assert(res == 0);
324#   endif
325}
326
327void recursive_mutex::do_lock()
328{
329    int res = 0;
330    res = pthread_mutex_lock(&m_mutex);
331    assert(res == 0);
332
333#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
334    if (++m_count > 1)
335    {
336        res = pthread_mutex_unlock(&m_mutex);
337        assert(res == 0);
338    }
339#   else
340    pthread_t tid = pthread_self();
341    if (m_valid_id && pthread_equal(m_thread_id, tid))
342        ++m_count;
343    else
344    {
345        while (m_valid_id)
346        {
347            res = pthread_cond_wait(&m_unlocked, &m_mutex);
348            assert(res == 0);
349        }
350
351        m_thread_id = tid;
352        m_valid_id = true;
353        m_count = 1;
354    }
355
356    res = pthread_mutex_unlock(&m_mutex);
357    assert(res == 0);
358#   endif
359}
360
361void recursive_mutex::do_unlock()
362{
363#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
364    if (--m_count == 0)
365    {
366        int res = 0;
367        res = pthread_mutex_unlock(&m_mutex);
368        assert(res == 0);
369    }
370#   else
371    int res = 0;
372    res = pthread_mutex_lock(&m_mutex);
373    assert(res == 0);
374
375    pthread_t tid = pthread_self();
376    if (m_valid_id && !pthread_equal(m_thread_id, tid))
377    {
378        res = pthread_mutex_unlock(&m_mutex);
379        assert(res == 0);
380        throw lock_error();
381    }
382
383    if (--m_count == 0)
384    {
385        assert(m_valid_id);
386        m_valid_id = false;
387
388        res = pthread_cond_signal(&m_unlocked);
389        assert(res == 0);
390    }
391
392    res = pthread_mutex_unlock(&m_mutex);
393    assert(res == 0);
394#   endif
395}
396
397void recursive_mutex::do_lock(cv_state& state)
398{
399#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
400    m_count = state.count;
401#   else
402    int res = 0;
403
404    while (m_valid_id)
405    {
406        res = pthread_cond_wait(&m_unlocked, &m_mutex);
407        assert(res == 0);
408    }
409
410    m_thread_id = pthread_self();
411    m_valid_id = true;
412    m_count = state.count;
413
414    res = pthread_mutex_unlock(&m_mutex);
415    assert(res == 0);
416#   endif
417}
418
419void recursive_mutex::do_unlock(cv_state& state)
420{
421#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
422    int res = 0;
423    res = pthread_mutex_lock(&m_mutex);
424    assert(res == 0);
425
426    assert(m_valid_id);
427    m_valid_id = false;
428
429    res = pthread_cond_signal(&m_unlocked);
430    assert(res == 0);
431#   endif
432
433    state.pmutex = &m_mutex;
434    state.count = m_count;
435    m_count = 0;
436}
437
438recursive_try_mutex::recursive_try_mutex()
439    : m_count(0)
440#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
441    , m_valid_id(false)
442#   endif
443{
444    pthread_mutexattr_t attr;
445    int res = pthread_mutexattr_init(&attr);
446    assert(res == 0);
447
448#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
449    res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
450    assert(res == 0);
451#   endif
452
453    res = pthread_mutex_init(&m_mutex, &attr);
454    {
455        int res = pthread_mutexattr_destroy(&attr);
456        assert(res == 0);
457    }
458    if (res != 0)
459        throw thread_resource_error();
460
461#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
462    res = pthread_cond_init(&m_unlocked, 0);
463    if (res != 0)
464    {
465        pthread_mutex_destroy(&m_mutex);
466        throw thread_resource_error();
467    }
468#   endif
469}
470
471recursive_try_mutex::~recursive_try_mutex()
472{
473    int res = 0;
474    res = pthread_mutex_destroy(&m_mutex);
475    assert(res == 0);
476
477#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
478    res = pthread_cond_destroy(&m_unlocked);
479    assert(res == 0);
480#   endif
481}
482
483void recursive_try_mutex::do_lock()
484{
485    int res = 0;
486    res = pthread_mutex_lock(&m_mutex);
487    assert(res == 0);
488
489#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
490    if (++m_count > 1)
491    {
492        res = pthread_mutex_unlock(&m_mutex);
493        assert(res == 0);
494    }
495#   else
496    pthread_t tid = pthread_self();
497    if (m_valid_id && pthread_equal(m_thread_id, tid))
498        ++m_count;
499    else
500    {
501        while (m_valid_id)
502        {
503            res = pthread_cond_wait(&m_unlocked, &m_mutex);
504            assert(res == 0);
505        }
506
507        m_thread_id = tid;
508        m_valid_id = true;
509        m_count = 1;
510    }
511
512    res = pthread_mutex_unlock(&m_mutex);
513    assert(res == 0);
514#   endif
515}
516
517bool recursive_try_mutex::do_trylock()
518{
519#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
520    int res = 0;
521    res = pthread_mutex_trylock(&m_mutex);
522    assert(res == 0 || res == EBUSY);
523
524    if (res == 0)
525    {
526        if (++m_count > 1)
527        {
528            res = pthread_mutex_unlock(&m_mutex);
529            assert(res == 0);
530        }
531        return true;
532    }
533
534    return false;
535#   else
536    int res = 0;
537    res = pthread_mutex_lock(&m_mutex);
538    assert(res == 0);
539
540    bool ret = false;
541    pthread_t tid = pthread_self();
542    if (m_valid_id && pthread_equal(m_thread_id, tid))
543    {
544        ++m_count;
545        ret = true;
546    }
547    else if (!m_valid_id)
548    {
549        m_thread_id = tid;
550        m_valid_id = true;
551        m_count = 1;
552        ret = true;
553    }
554
555    res = pthread_mutex_unlock(&m_mutex);
556    assert(res == 0);
557    return ret;
558#   endif
559}
560
561void recursive_try_mutex::do_unlock()
562{
563#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
564    if (--m_count == 0)
565    {
566        int res = 0;
567        res = pthread_mutex_unlock(&m_mutex);
568        assert(res == 0);
569    }
570#   else
571    int res = 0;
572    res = pthread_mutex_lock(&m_mutex);
573    assert(res == 0);
574
575    pthread_t tid = pthread_self();
576    if (m_valid_id && !pthread_equal(m_thread_id, tid))
577    {
578        res = pthread_mutex_unlock(&m_mutex);
579        assert(res == 0);
580        throw lock_error();
581    }
582
583    if (--m_count == 0)
584    {
585        assert(m_valid_id);
586        m_valid_id = false;
587
588        res = pthread_cond_signal(&m_unlocked);
589        assert(res == 0);
590    }
591
592    res = pthread_mutex_unlock(&m_mutex);
593    assert(res == 0);
594#   endif
595}
596
597void recursive_try_mutex::do_lock(cv_state& state)
598{
599#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
600    m_count = state.count;
601#   else
602    int res = 0;
603
604    while (m_valid_id)
605    {
606        res = pthread_cond_wait(&m_unlocked, &m_mutex);
607        assert(res == 0);
608    }
609
610    m_thread_id = pthread_self();
611    m_valid_id = true;
612    m_count = state.count;
613
614    res = pthread_mutex_unlock(&m_mutex);
615    assert(res == 0);
616#   endif
617}
618
619void recursive_try_mutex::do_unlock(cv_state& state)
620{
621#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
622    int res = 0;
623    res = pthread_mutex_lock(&m_mutex);
624    assert(res == 0);
625
626    assert(m_valid_id);
627    m_valid_id = false;
628
629    res = pthread_cond_signal(&m_unlocked);
630    assert(res == 0);
631#   endif
632
633    state.pmutex = &m_mutex;
634    state.count = m_count;
635    m_count = 0;
636}
637
638recursive_timed_mutex::recursive_timed_mutex()
639    : m_valid_id(false), m_count(0)
640{
641    int res = 0;
642    res = pthread_mutex_init(&m_mutex, 0);
643    if (res != 0)
644        throw thread_resource_error();
645
646    res = pthread_cond_init(&m_unlocked, 0);
647    if (res != 0)
648    {
649        pthread_mutex_destroy(&m_mutex);
650        throw thread_resource_error();
651    }
652}
653
654recursive_timed_mutex::~recursive_timed_mutex()
655{
656    int res = 0;
657    res = pthread_mutex_destroy(&m_mutex);
658    assert(res == 0);
659
660    res = pthread_cond_destroy(&m_unlocked);
661    assert(res == 0);
662}
663
664void recursive_timed_mutex::do_lock()
665{
666    int res = 0;
667    res = pthread_mutex_lock(&m_mutex);
668    assert(res == 0);
669
670    pthread_t tid = pthread_self();
671    if (m_valid_id && pthread_equal(m_thread_id, tid))
672        ++m_count;
673    else
674    {
675        while (m_valid_id)
676        {
677            res = pthread_cond_wait(&m_unlocked, &m_mutex);
678            assert(res == 0);
679        }
680
681        m_thread_id = tid;
682        m_valid_id = true;
683        m_count = 1;
684    }
685
686    res = pthread_mutex_unlock(&m_mutex);
687    assert(res == 0);
688}
689
690bool recursive_timed_mutex::do_trylock()
691{
692    int res = 0;
693    res = pthread_mutex_lock(&m_mutex);
694    assert(res == 0);
695
696    bool ret = false;
697    pthread_t tid = pthread_self();
698    if (m_valid_id && pthread_equal(m_thread_id, tid))
699    {
700        ++m_count;
701        ret = true;
702    }
703    else if (!m_valid_id)
704    {
705        m_thread_id = tid;
706        m_valid_id = true;
707        m_count = 1;
708        ret = true;
709    }
710
711    res = pthread_mutex_unlock(&m_mutex);
712    assert(res == 0);
713    return ret;
714}
715
716bool recursive_timed_mutex::do_timedlock(const xtime& xt)
717{
718    int res = 0;
719    res = pthread_mutex_lock(&m_mutex);
720    assert(res == 0);
721
722    bool ret = false;
723    pthread_t tid = pthread_self();
724    if (m_valid_id && pthread_equal(m_thread_id, tid))
725    {
726        ++m_count;
727        ret = true;
728    }
729    else
730    {
731        timespec ts;
732        to_timespec(xt, ts);
733
734        while (m_valid_id)
735        {
736            res = pthread_cond_timedwait(&m_unlocked, &m_mutex, &ts);
737            if (res == ETIMEDOUT)
738                break;
739            assert(res == 0);
740        }
741
742        if (!m_valid_id)
743        {
744            m_thread_id = tid;
745            m_valid_id = true;
746            m_count = 1;
747            ret = true;
748        }
749    }
750
751    res = pthread_mutex_unlock(&m_mutex);
752    assert(res == 0);
753    return ret;
754}
755
756void recursive_timed_mutex::do_unlock()
757{
758    int res = 0;
759    res = pthread_mutex_lock(&m_mutex);
760    assert(res == 0);
761
762    pthread_t tid = pthread_self();
763    if (m_valid_id && !pthread_equal(m_thread_id, tid))
764    {
765        res = pthread_mutex_unlock(&m_mutex);
766        assert(res == 0);
767        throw lock_error();
768    }
769
770    if (--m_count == 0)
771    {
772        assert(m_valid_id);
773        m_valid_id = false;
774
775        res = pthread_cond_signal(&m_unlocked);
776        assert(res == 0);
777    }
778
779    res = pthread_mutex_unlock(&m_mutex);
780    assert(res == 0);
781}
782
783void recursive_timed_mutex::do_lock(cv_state& state)
784{
785    int res = 0;
786
787    while (m_valid_id)
788    {
789        res = pthread_cond_wait(&m_unlocked, &m_mutex);
790        assert(res == 0);
791    }
792
793    m_thread_id = pthread_self();
794    m_valid_id = true;
795    m_count = state.count;
796
797    res = pthread_mutex_unlock(&m_mutex);
798    assert(res == 0);
799}
800
801void recursive_timed_mutex::do_unlock(cv_state& state)
802{
803    int res = 0;
804    res = pthread_mutex_lock(&m_mutex);
805    assert(res == 0);
806
807    assert(m_valid_id);
808    m_valid_id = false;
809
810    res = pthread_cond_signal(&m_unlocked);
811    assert(res == 0);
812
813    state.pmutex = &m_mutex;
814    state.count = m_count;
815    m_count = 0;
816}
817#elif defined(BOOST_HAS_MPTASKS)
818
819using threads::mac::detail::safe_enter_critical_region;
820
821
822recursive_mutex::recursive_mutex()
823    : m_count(0)
824{
825}
826
827recursive_mutex::~recursive_mutex()
828{
829}
830
831void recursive_mutex::do_lock()
832{
833    OSStatus lStatus = noErr;
834    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
835        m_mutex_mutex);
836    assert(lStatus == noErr);
837
838    if (++m_count > 1)
839    {
840        lStatus = MPExitCriticalRegion(m_mutex);
841        assert(lStatus == noErr);
842    }
843}
844
845void recursive_mutex::do_unlock()
846{
847    if (--m_count == 0)
848    {
849        OSStatus lStatus = noErr;
850        lStatus = MPExitCriticalRegion(m_mutex);
851        assert(lStatus == noErr);
852    }
853}
854
855void recursive_mutex::do_lock(cv_state& state)
856{
857    OSStatus lStatus = noErr;
858    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
859        m_mutex_mutex);
860    assert(lStatus == noErr);
861
862    m_count = state;
863}
864
865void recursive_mutex::do_unlock(cv_state& state)
866{
867    state = m_count;
868    m_count = 0;
869
870    OSStatus lStatus = noErr;
871    lStatus = MPExitCriticalRegion(m_mutex);
872    assert(lStatus == noErr);
873}
874
875recursive_try_mutex::recursive_try_mutex()
876    : m_count(0)
877{
878}
879
880recursive_try_mutex::~recursive_try_mutex()
881{
882}
883
884void recursive_try_mutex::do_lock()
885{
886    OSStatus lStatus = noErr;
887    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
888        m_mutex_mutex);
889    assert(lStatus == noErr);
890
891    if (++m_count > 1)
892    {
893        lStatus = MPExitCriticalRegion(m_mutex);
894        assert(lStatus == noErr);
895    }
896}
897
898bool recursive_try_mutex::do_trylock()
899{
900    OSStatus lStatus = noErr;
901    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
902    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
903
904    if (lStatus == noErr)
905    {
906        if (++m_count > 1)
907        {
908            lStatus = MPExitCriticalRegion(m_mutex);
909            assert(lStatus == noErr);
910        }
911        return true;
912    }
913    return false;
914}
915
916void recursive_try_mutex::do_unlock()
917{
918    if (--m_count == 0)
919    {
920        OSStatus lStatus = noErr;
921        lStatus = MPExitCriticalRegion(m_mutex);
922        assert(lStatus == noErr);
923    }
924}
925
926void recursive_try_mutex::do_lock(cv_state& state)
927{
928    OSStatus lStatus = noErr;
929    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
930        m_mutex_mutex);
931    assert(lStatus == noErr);
932
933    m_count = state;
934}
935
936void recursive_try_mutex::do_unlock(cv_state& state)
937{
938    state = m_count;
939    m_count = 0;
940
941    OSStatus lStatus = noErr;
942    lStatus = MPExitCriticalRegion(m_mutex);
943    assert(lStatus == noErr);
944}
945
946recursive_timed_mutex::recursive_timed_mutex()
947    : m_count(0)
948{
949}
950
951recursive_timed_mutex::~recursive_timed_mutex()
952{
953}
954
955void recursive_timed_mutex::do_lock()
956{
957    OSStatus lStatus = noErr;
958    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
959        m_mutex_mutex);
960    assert(lStatus == noErr);
961
962    if (++m_count > 1)
963    {
964        lStatus = MPExitCriticalRegion(m_mutex);
965        assert(lStatus == noErr);
966    }
967}
968
969bool recursive_timed_mutex::do_trylock()
970{
971    OSStatus lStatus = noErr;
972    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
973    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
974
975    if (lStatus == noErr)
976    {
977        if (++m_count > 1)
978        {
979            lStatus = MPExitCriticalRegion(m_mutex);
980            assert(lStatus == noErr);
981        }
982        return true;
983    }
984    return false;
985}
986
987bool recursive_timed_mutex::do_timedlock(const xtime& xt)
988{
989    int microseconds;
990    to_microduration(xt, microseconds);
991    Duration lDuration = kDurationMicrosecond * microseconds;
992
993    OSStatus lStatus = noErr;
994    lStatus = safe_enter_critical_region(m_mutex, lDuration, m_mutex_mutex);
995    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
996
997    if (lStatus == noErr)
998    {
999        if (++m_count > 1)
1000        {
1001            lStatus = MPExitCriticalRegion(m_mutex);
1002            assert(lStatus == noErr);
1003        }
1004        return true;
1005    }
1006    return false;
1007}
1008
1009void recursive_timed_mutex::do_unlock()
1010{
1011    if (--m_count == 0)
1012    {
1013        OSStatus lStatus = noErr;
1014        lStatus = MPExitCriticalRegion(m_mutex);
1015        assert(lStatus == noErr);
1016    }
1017}
1018
1019void recursive_timed_mutex::do_lock(cv_state& state)
1020{
1021    OSStatus lStatus = noErr;
1022    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
1023        m_mutex_mutex);
1024    assert(lStatus == noErr);
1025
1026    m_count = state;
1027}
1028
1029void recursive_timed_mutex::do_unlock(cv_state& state)
1030{
1031    state = m_count;
1032    m_count = 0;
1033
1034    OSStatus lStatus = noErr;
1035    lStatus = MPExitCriticalRegion(m_mutex);
1036    assert(lStatus == noErr);
1037}
1038#endif
1039
1040} // namespace boost
1041
1042// Change Log:
1043//   8 Feb 01  WEKEMPF Initial version.
Note: See TracBrowser for help on using the repository browser.