diff --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp --- a/libcxxabi/src/fallback_malloc.cpp +++ b/libcxxabi/src/fallback_malloc.cpp @@ -41,14 +41,28 @@ class mutexor { public: -#ifndef _LIBCXXABI_HAS_NO_THREADS - mutexor(std::__libcpp_mutex_t* m) : mtx_(m) { - std::__libcpp_mutex_lock(mtx_); - } - ~mutexor() { std::__libcpp_mutex_unlock(mtx_); } -#else +#ifdef _LIBCXXABI_HAS_NO_THREADS mutexor(void*) {} ~mutexor() {} +#else + mutexor(std::__libcpp_mutex_t* m) { + // Neither fallback_malloc nor fallback_free spawn new threads. Thus, there + // is no danger of one thread entering them without aquiring the mutex, + // followed by another thread entering (and aquiring the mutex) before the + // first thread leaves. + // We can't acquire mutexes when the threading API is disabled, but since + // we don't need to unless there is more than one thread anyways, we only + // bother to aquire the mutex when multi-threaded. + if (std::__libcpp_might_have_multiple_threads()) { + mtx_ = m; + std::__libcpp_mutex_lock(mtx_); + } else + mtx_ = nullptr; + } + ~mutexor() { + if (mtx_ != nullptr) + std::__libcpp_mutex_unlock(mtx_); + } #endif private: mutexor(const mutexor& rhs);