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

Reply via email to