mutex.cpp revision b64f8b07c104c6cc986570ac8ee0ed16a9f23976
1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===------------------------- mutex.cpp ----------------------------------===//
2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant//                     The LLVM Compiler Infrastructure
4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===//
9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "mutex"
11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "limits"
12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "system_error"
13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "cassert"
14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst defer_lock_t  defer_lock = {};
18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst try_to_lock_t try_to_lock = {};
19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst adopt_lock_t  adopt_lock = {};
20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::~mutex()
22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int e = pthread_mutex_destroy(&__m_);
24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//     assert(e == 0);
25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::lock()
29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int ec = pthread_mutex_lock(&__m_);
31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __throw_system_error(ec, "mutex lock failed");
33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::try_lock()
37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return pthread_mutex_trylock(&__m_) == 0;
39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::unlock()
43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int ec = pthread_mutex_unlock(&__m_);
45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    assert(ec == 0);
46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// recursive_mutex
49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::recursive_mutex()
51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    pthread_mutexattr_t attr;
53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int ec = pthread_mutexattr_init(&attr);
54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        goto fail;
56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pthread_mutexattr_destroy(&attr);
60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        goto fail;
61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ec = pthread_mutex_init(&__m_, &attr);
63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pthread_mutexattr_destroy(&attr);
66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        goto fail;
67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    ec = pthread_mutexattr_destroy(&attr);
69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pthread_mutex_destroy(&__m_);
72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        goto fail;
73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return;
75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantfail:
76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __throw_system_error(ec, "recursive_mutex constructor failed");
77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::~recursive_mutex()
80bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
81bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int e = pthread_mutex_destroy(&__m_);
82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    assert(e == 0);
83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
84bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::lock()
87bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
88bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int ec = pthread_mutex_lock(&__m_);
89bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (ec)
90bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __throw_system_error(ec, "recursive_mutex lock failed");
91bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
92bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
93bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
94bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::unlock()
95bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
96bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    int e = pthread_mutex_unlock(&__m_);
97bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    assert(e == 0);
98bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
99bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
100bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
101bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::try_lock()
102bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
103bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return pthread_mutex_trylock(&__m_) == 0;
104bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
105bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
106bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// timed_mutex
107bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
108bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::timed_mutex()
109bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : __locked_(false)
110bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
111bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
112bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
113bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::~timed_mutex()
114bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
115bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    lock_guard<mutex> _(__m_);
116bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
117bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
118bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
119bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::lock()
120bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
121bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    unique_lock<mutex> lk(__m_);
122bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    while (__locked_)
123bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __cv_.wait(lk);
124bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __locked_ = true;
125bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
126bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
127bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
128bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::try_lock()
129bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
130bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    unique_lock<mutex> lk(__m_, try_to_lock);
131bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (lk.owns_lock() && !__locked_)
132bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
133bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __locked_ = true;
134bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return true;
135bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
136bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return false;
137bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
138bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
139bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
140bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::unlock()
141bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
142bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    lock_guard<mutex> _(__m_);
143bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __locked_ = false;
144bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __cv_.notify_one();
145bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
146bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
147bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// recursive_timed_mutex
148bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
149bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::recursive_timed_mutex()
150bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    : __count_(0),
151adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant      __id_(0)
152bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
153bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
154bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
155bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::~recursive_timed_mutex()
156bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
157bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    lock_guard<mutex> _(__m_);
158bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
159bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
160bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
161bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::lock()
162bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
163bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    pthread_t id = pthread_self();
164bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    unique_lock<mutex> lk(__m_);
165bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (pthread_equal(id, __id_))
166bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
167bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        if (__count_ == numeric_limits<size_t>::max())
168bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached");
169bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        ++__count_;
170bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return;
171bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
172bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    while (__count_ != 0)
173bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __cv_.wait(lk);
174bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __count_ = 1;
175bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    __id_ = id;
176bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
177bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
178bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool
179bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::try_lock()
180bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
181bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    pthread_t id = pthread_self();
182bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    unique_lock<mutex> lk(__m_, try_to_lock);
183bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_)))
184bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
185bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        if (__count_ == numeric_limits<size_t>::max())
186bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            return false;
187bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        ++__count_;
188bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __id_ = id;
189bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return true;
190bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
191bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    return false;
192bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
193bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
194bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
195bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::unlock()
196bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
197bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    unique_lock<mutex> lk(__m_);
198bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (--__count_ == 0)
199bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
200adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant        __id_ = 0;
201bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        lk.unlock();
202bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        __cv_.notify_one();
203bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
204bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
205bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
206bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// If dispatch_once_f ever handles C++ exceptions, and if one can get to it
207bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// without illegal macros (unexpected macros not beginning with _UpperCase or
208bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// __lowercase), and if it stops spinning waiting threads, then call_once should
209bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// call into dispatch_once_f instead of here. Relevant radar this code needs to
210bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// keep in sync with:  7741191.
211bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
212bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
213bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic pthread_cond_t  cv  = PTHREAD_COND_INITIALIZER;
214bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
215bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid
216bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
217bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
218bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    pthread_mutex_lock(&mut);
219bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    while (flag == 1)
220bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pthread_cond_wait(&cv, &mut);
221bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    if (flag == 0)
222bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
223d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
224bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        try
225bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        {
22616e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
227bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            flag = 1;
228bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_mutex_unlock(&mut);
229bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            func(arg);
230bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_mutex_lock(&mut);
231bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            flag = ~0ul;
232bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_mutex_unlock(&mut);
233bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_cond_broadcast(&cv);
234d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
235bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        }
236bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        catch (...)
237bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        {
238bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_mutex_lock(&mut);
239bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            flag = 0ul;
240bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            pthread_mutex_unlock(&mut);
24121aefc3a6135c6447b8b43ac3f2349bf568e2900Howard Hinnant            pthread_cond_broadcast(&cv);
242bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            throw;
243bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        }
24416e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
245bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
246bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    else
247bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        pthread_mutex_unlock(&mut);
248bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
249bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
250bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_END_NAMESPACE_STD
251