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
This commit is contained in:
@@ -5541,14 +5541,17 @@ template <class _Tp>
|
|||||||
bool
|
bool
|
||||||
atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
|
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);
|
__sp_mut& __m = __get_sp_mut(__p);
|
||||||
__m.lock();
|
__m.lock();
|
||||||
if (__p->__owner_equivalent(*__v))
|
if (__p->__owner_equivalent(*__v))
|
||||||
{
|
{
|
||||||
|
_VSTD::swap(__temp, *__p);
|
||||||
*__p = __w;
|
*__p = __w;
|
||||||
__m.unlock();
|
__m.unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
_VSTD::swap(__temp, *__v);
|
||||||
*__v = *__p;
|
*__v = *__p;
|
||||||
__m.unlock();
|
__m.unlock();
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user