]> granicus.if.org Git - python/commitdiff
Defer deleted item decref until after the deque is restored to a consistent state.
authorRaymond Hettinger <python@rcn.com>
Sat, 2 May 2015 17:53:27 +0000 (10:53 -0700)
committerRaymond Hettinger <python@rcn.com>
Sat, 2 May 2015 17:53:27 +0000 (10:53 -0700)
Misc/NEWS
Modules/_collectionsmodule.c

index 2ed2963035c506c639b7f468dd2e398c8be0a808..ad958d8b72724f4d4be470349425814a53c15ee7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -26,6 +26,10 @@ Library
 - Issues #24099, #24100, and #24101: Fix free-after-use bug in heapq's siftup
   and siftdown functions.
 
+- Backport collections.deque fixes from Python 3.5.  Prevents reentrant badness
+  during deletion by deferring the decref until the container has been restored
+  to a consistent state.
+
 - Issue #23842: os.major(), os.minor() and os.makedev() now support ints again.
 
 - Issue #23811: Add missing newline to the PyCompileError error message.
index bcdffcba92b60e2541ccd6d3064e0f8d9109cd0b..1924374b9c34827a9f1fbb69268ab749cda33a24 100644 (file)
@@ -623,9 +623,9 @@ deque_remove(dequeobject *deque, PyObject *value)
         if (cmp > 0) {
             PyObject *tgt = deque_popleft(deque, NULL);
             assert (tgt != NULL);
-            Py_DECREF(tgt);
-            if (_deque_rotate(deque, i) == -1)
+            if (_deque_rotate(deque, i))
                 return NULL;
+            Py_DECREF(tgt);
             Py_RETURN_NONE;
         }
         else if (cmp < 0) {
@@ -706,16 +706,16 @@ static int
 deque_del_item(dequeobject *deque, Py_ssize_t i)
 {
     PyObject *item;
+    int rv;
 
-    assert (i >= 0 && i < deque->len);
-    if (_deque_rotate(deque, -i) == -1)
+    assert (i >= 0 && i < Py_SIZE(deque));
+    if (_deque_rotate(deque, -i))
         return -1;
-
     item = deque_popleft(deque, NULL);
+    rv = _deque_rotate(deque, i);
     assert (item != NULL);
     Py_DECREF(item);
-
-    return _deque_rotate(deque, i);
+    return rv;
 }
 
 static int