From 2241cf0d5b5f18a51877b8fa4bcccde92fa675ad Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Wed, 18 May 2016 17:50:13 +0000 Subject: [PATCH] Change the control flow in atomic_compare_exchange_strong to avoid a potential deadlock. When you assign a shared_ptr, the deleter gets called and assigned. In this routine, the assignment happens inside a critical section, which could (potentially) lead to a deadlock, if the deleter did something wonky. Now we swap the old value with an (empty) temporary shared_ptr, and then let the temporary delete the old value when it goes out of scope (after the lock has been released). This should fix PR#27724. Thanks to Hans Boehm for the bug report and the suggested fix. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@269965 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/memory b/include/memory index 8378aef49..7627248a4 100644 --- a/include/memory +++ b/include/memory @@ -5541,14 +5541,17 @@ template bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { + shared_ptr<_Tp> __temp; __sp_mut& __m = __get_sp_mut(__p); __m.lock(); if (__p->__owner_equivalent(*__v)) { + _VSTD::swap(__temp, *__p); *__p = __w; __m.unlock(); return true; } + _VSTD::swap(__temp, *__v); *__v = *__p; __m.unlock(); return false;