summaryrefslogtreecommitdiff
path: root/libcxx/src
diff options
context:
space:
mode:
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>2023-01-10 13:29:35 -0500
committerLouis Dionne <ldionne.2@gmail.com>2023-01-11 17:01:21 -0500
commit64fc3cd55d586498dd21c5b3cfaa755793913772 (patch)
treeab90d154c0acf151ae57ffd89a3206ae2cc92c80 /libcxx/src
parent6e5cbc097a5ac7fa95a8f425af8b03958151c763 (diff)
downloadllvm-64fc3cd55d586498dd21c5b3cfaa755793913772.tar.gz
[libc++] Hold mutex lock while notify_all is called at notify_all_at_thread_exit
Releasing the mutex before the call to notify_all is an optimization. This optimization cannot be used here. The thread waiting on the condition might destroy the associated resources — mutex + condition variable — and the notifier thread will access an destroyed variable — the condition variable. In fact, notify_all_at_thread_exit is meant exactly to join on detached threads, and the waiting thread doesn't expect for the notifier thread to access any further shared resources, making this scenario very likely to happen. The waiting thread might awake spuriously on the release of the mutex lock. The reorder is necessary to prevent this race. Further details can be found at https://cplusplus.github.io/LWG/issue3343. Differential Revision: https://reviews.llvm.org/D105758
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/thread.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index ce2822dbac85..ec4f65f9823b 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -164,8 +164,8 @@ __thread_struct_imp::~__thread_struct_imp()
for (_Notify::iterator i = notify_.begin(), e = notify_.end();
i != e; ++i)
{
- i->second->unlock();
i->first->notify_all();
+ i->second->unlock();
}
for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end();
i != e; ++i)