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 10499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnant#define _LIBCPP_BUILDING_MUTEX 11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "mutex" 12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "limits" 13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "system_error" 14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "cassert" 15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 177112dae6acac544a0271a85d95342c583441e2d1Dan Albert#ifndef _LIBCPP_HAS_NO_THREADS 18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst defer_lock_t defer_lock = {}; 20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst try_to_lock_t try_to_lock = {}; 21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantconst adopt_lock_t adopt_lock = {}; 22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::~mutex() 24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 25ec3773c2dadbeadfc5def927116c2ee9d9c53066Howard Hinnant pthread_mutex_destroy(&__m_); 26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantmutex::lock() 30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int ec = pthread_mutex_lock(&__m_); 32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __throw_system_error(ec, "mutex lock failed"); 34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool 37499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantmutex::try_lock() _NOEXCEPT 38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return pthread_mutex_trylock(&__m_) == 0; 40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 43499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantmutex::unlock() _NOEXCEPT 44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int ec = pthread_mutex_unlock(&__m_); 46fc910cb9a0b5a1ecd8b1f4c1c10ca54e2e433aa7Howard Hinnant (void)ec; 47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(ec == 0); 48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// recursive_mutex 51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::recursive_mutex() 53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutexattr_t attr; 55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int ec = pthread_mutexattr_init(&attr); 56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant goto fail; 58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutexattr_destroy(&attr); 62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant goto fail; 63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ec = pthread_mutex_init(&__m_, &attr); 65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutexattr_destroy(&attr); 68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant goto fail; 69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ec = pthread_mutexattr_destroy(&attr); 71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_destroy(&__m_); 74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant goto fail; 75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return; 77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantfail: 78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __throw_system_error(ec, "recursive_mutex constructor failed"); 79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 80bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 81bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::~recursive_mutex() 82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int e = pthread_mutex_destroy(&__m_); 84fc910cb9a0b5a1ecd8b1f4c1c10ca54e2e433aa7Howard Hinnant (void)e; 85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(e == 0); 86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 87bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 88bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 89bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_mutex::lock() 90bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 91bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int ec = pthread_mutex_lock(&__m_); 92bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (ec) 93bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __throw_system_error(ec, "recursive_mutex lock failed"); 94bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 95bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 96bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 97499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantrecursive_mutex::unlock() _NOEXCEPT 98bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 99bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int e = pthread_mutex_unlock(&__m_); 100fc910cb9a0b5a1ecd8b1f4c1c10ca54e2e433aa7Howard Hinnant (void)e; 101bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(e == 0); 102bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 103bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 104bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool 105499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantrecursive_mutex::try_lock() _NOEXCEPT 106bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 107bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return pthread_mutex_trylock(&__m_) == 0; 108bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 109bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 110bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// timed_mutex 111bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 112bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::timed_mutex() 113bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant : __locked_(false) 114bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 115bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 116bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 117bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::~timed_mutex() 118bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 119bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant lock_guard<mutex> _(__m_); 120bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 121bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 122bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 123bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttimed_mutex::lock() 124bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 125bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant unique_lock<mutex> lk(__m_); 126bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant while (__locked_) 127bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __cv_.wait(lk); 128bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __locked_ = true; 129bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 130bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 131bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool 132499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnanttimed_mutex::try_lock() _NOEXCEPT 133bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 134bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant unique_lock<mutex> lk(__m_, try_to_lock); 135bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (lk.owns_lock() && !__locked_) 136bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 137bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __locked_ = true; 138bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return true; 139bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 140bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return false; 141bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 142bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 143bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 144499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnanttimed_mutex::unlock() _NOEXCEPT 145bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 146bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant lock_guard<mutex> _(__m_); 147bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __locked_ = false; 148bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __cv_.notify_one(); 149bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 150bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 151bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// recursive_timed_mutex 152bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 153bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::recursive_timed_mutex() 154bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant : __count_(0), 155adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant __id_(0) 156bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 157bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 158bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 159bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::~recursive_timed_mutex() 160bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 161bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant lock_guard<mutex> _(__m_); 162bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 163bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 164bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 165bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantrecursive_timed_mutex::lock() 166bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 167bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_t id = pthread_self(); 168bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant unique_lock<mutex> lk(__m_); 169bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (pthread_equal(id, __id_)) 170bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 171bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (__count_ == numeric_limits<size_t>::max()) 172bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); 173bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ++__count_; 174bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return; 175bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 176bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant while (__count_ != 0) 177bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __cv_.wait(lk); 178bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __count_ = 1; 179bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __id_ = id; 180bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 181bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 182bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool 183499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantrecursive_timed_mutex::try_lock() _NOEXCEPT 184bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 185bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_t id = pthread_self(); 186bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant unique_lock<mutex> lk(__m_, try_to_lock); 187bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_))) 188bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 189bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (__count_ == numeric_limits<size_t>::max()) 190bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return false; 191bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ++__count_; 192bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __id_ = id; 193bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return true; 194bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 195bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return false; 196bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 197bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 198bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 199499c61f999dd032510ecd4a70c90bf4410c9762bHoward Hinnantrecursive_timed_mutex::unlock() _NOEXCEPT 200bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 201bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant unique_lock<mutex> lk(__m_); 202bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (--__count_ == 0) 203bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 204adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant __id_ = 0; 205bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant lk.unlock(); 206bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant __cv_.notify_one(); 207bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 208bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 209bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 2107112dae6acac544a0271a85d95342c583441e2d1Dan Albert#endif // !_LIBCPP_HAS_NO_THREADS 2117112dae6acac544a0271a85d95342c583441e2d1Dan Albert 212bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// If dispatch_once_f ever handles C++ exceptions, and if one can get to it 213bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// without illegal macros (unexpected macros not beginning with _UpperCase or 214bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// __lowercase), and if it stops spinning waiting threads, then call_once should 215bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// call into dispatch_once_f instead of here. Relevant radar this code needs to 216bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// keep in sync with: 7741191. 217bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 2187112dae6acac544a0271a85d95342c583441e2d1Dan Albert#ifndef _LIBCPP_HAS_NO_THREADS 219bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; 220bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 2217112dae6acac544a0271a85d95342c583441e2d1Dan Albert#endif 222bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 223bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid 224bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) 225bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 2267112dae6acac544a0271a85d95342c583441e2d1Dan Albert#if defined(_LIBCPP_HAS_NO_THREADS) 2277112dae6acac544a0271a85d95342c583441e2d1Dan Albert if (flag == 0) 2287112dae6acac544a0271a85d95342c583441e2d1Dan Albert { 2297112dae6acac544a0271a85d95342c583441e2d1Dan Albert#ifndef _LIBCPP_NO_EXCEPTIONS 2307112dae6acac544a0271a85d95342c583441e2d1Dan Albert try 2317112dae6acac544a0271a85d95342c583441e2d1Dan Albert { 2327112dae6acac544a0271a85d95342c583441e2d1Dan Albert#endif // _LIBCPP_NO_EXCEPTIONS 2337112dae6acac544a0271a85d95342c583441e2d1Dan Albert flag = 1; 2347112dae6acac544a0271a85d95342c583441e2d1Dan Albert func(arg); 2357112dae6acac544a0271a85d95342c583441e2d1Dan Albert flag = ~0ul; 2367112dae6acac544a0271a85d95342c583441e2d1Dan Albert#ifndef _LIBCPP_NO_EXCEPTIONS 2377112dae6acac544a0271a85d95342c583441e2d1Dan Albert } 2387112dae6acac544a0271a85d95342c583441e2d1Dan Albert catch (...) 2397112dae6acac544a0271a85d95342c583441e2d1Dan Albert { 2407112dae6acac544a0271a85d95342c583441e2d1Dan Albert flag = 0ul; 2417112dae6acac544a0271a85d95342c583441e2d1Dan Albert throw; 2427112dae6acac544a0271a85d95342c583441e2d1Dan Albert } 2437112dae6acac544a0271a85d95342c583441e2d1Dan Albert#endif // _LIBCPP_NO_EXCEPTIONS 2447112dae6acac544a0271a85d95342c583441e2d1Dan Albert } 2457112dae6acac544a0271a85d95342c583441e2d1Dan Albert#else // !_LIBCPP_HAS_NO_THREADS 246bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_lock(&mut); 247bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant while (flag == 1) 248bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_cond_wait(&cv, &mut); 249bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (flag == 0) 250bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 251d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 252bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant try 253bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 25416e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 255bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant flag = 1; 256bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_unlock(&mut); 257bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant func(arg); 258bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_lock(&mut); 259bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant flag = ~0ul; 260bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_unlock(&mut); 261bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_cond_broadcast(&cv); 262d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 263bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 264bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant catch (...) 265bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 266bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_lock(&mut); 267bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant flag = 0ul; 268bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_unlock(&mut); 26921aefc3a6135c6447b8b43ac3f2349bf568e2900Howard Hinnant pthread_cond_broadcast(&cv); 270bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant throw; 271bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 27216e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 273bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 274bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant else 275bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant pthread_mutex_unlock(&mut); 2767112dae6acac544a0271a85d95342c583441e2d1Dan Albert#endif // !_LIBCPP_HAS_NO_THREADS 2777112dae6acac544a0271a85d95342c583441e2d1Dan Albert 278bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 279bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 280bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_END_NAMESPACE_STD 281