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