Author: marshall Date: Wed May 18 12:50:13 2016 New Revision: 269965 URL: http://llvm.org/viewvc/llvm-project?rev=269965&view=rev Log: 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. Modified: libcxx/trunk/include/memory Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=269965&r1=269964&r2=269965&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Wed May 18 12:50:13 2016 @@ -5541,14 +5541,17 @@ template <class _Tp> 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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits