From: Raymond Hettinger Date: Sat, 2 May 2015 17:53:27 +0000 (-0700) Subject: Defer deleted item decref until after the deque is restored to a consistent state. X-Git-Tag: v2.7.10rc1~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=79f2c5b8e0b110724290c04eb1883a4c747f5591;p=thirdparty%2FPython%2Fcpython.git Defer deleted item decref until after the deque is restored to a consistent state. --- diff --git a/Misc/NEWS b/Misc/NEWS index 2ed2963035c5..ad958d8b7272 100644 --- 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. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index bcdffcba92b6..1924374b9c34 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -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