From: Antoine Pitrou Date: Wed, 5 Sep 2012 23:17:42 +0000 (+0200) Subject: Issue #13992: The trashcan mechanism is now thread-safe. This eliminates X-Git-Tag: v3.3.1rc1~818^2^2~140 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b4faae30748c09930fa053442e1d6ff2823823c;p=python Issue #13992: The trashcan mechanism is now thread-safe. This eliminates sporadic crashes in multi-thread programs when several long deallocator chains ran concurrently and involved subclasses of built-in container types. Note that the trashcan functions are part of the stable ABI, therefore they have to be kept around for binary compatibility of extensions. --- 5b4faae30748c09930fa053442e1d6ff2823823c diff --cc Include/object.h index 709a9fff13,6120ab813c..387cadb4e4 --- a/Include/object.h +++ b/Include/object.h @@@ -961,6 -911,8 +961,8 @@@ chain of N deallocations is broken int with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. */ + /* This is the old private API, invoked by the macros before 3.2.4. - Kept for binary compatibility of extensions. */ ++ Kept for binary compatibility of extensions using the stable ABI. */ PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); PyAPI_FUNC(void) _PyTrash_destroy_chain(void); PyAPI_DATA(int) _PyTrash_delete_nesting; @@@ -969,25 -925,20 +975,28 @@@ PyAPI_FUNC(void) _PyTrash_thread_destro #define PyTrash_UNWIND_LEVEL 50 #define Py_TRASHCAN_SAFE_BEGIN(op) \ - if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \ - ++_PyTrash_delete_nesting; - /* The body of the deallocator is here. */ + do { \ + PyThreadState *_tstate = PyThreadState_GET(); \ + if (_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL) { \ + ++_tstate->trash_delete_nesting; + /* The body of the deallocator is here. */ #define Py_TRASHCAN_SAFE_END(op) \ - --_PyTrash_delete_nesting; \ - if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \ - _PyTrash_destroy_chain(); \ - } \ - else \ - _PyTrash_deposit_object((PyObject*)op); + --_tstate->trash_delete_nesting; \ + if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \ + _PyTrash_thread_destroy_chain(); \ + } \ + else \ + _PyTrash_thread_deposit_object((PyObject*)op); \ + } while (0); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) +_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, + size_t sizeof_block); +PyAPI_FUNC(void) +_PyObject_DebugTypeStats(FILE *out); +#endif /* ifndef Py_LIMITED_API */ + #ifdef __cplusplus } #endif diff --cc Lib/test/test_gc.py index d35f9ed762,e1c124d160..c59b72eacf --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@@ -1,7 -1,7 +1,8 @@@ import unittest -from test.support import verbose, run_unittest, strip_python_stderr +from test.support import (verbose, refcount_test, run_unittest, + strip_python_stderr) import sys + import time import gc import weakref diff --cc Misc/NEWS index aaf3aef870,a1d35a4f1d..8046b7bf45 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -10,8 -10,11 +10,13 @@@ What's New in Python 3.3. Core and Builtins ----------------- + - Issue #13992: The trashcan mechanism is now thread-safe. This eliminates + sporadic crashes in multi-thread programs when several long deallocator + chains ran concurrently and involved subclasses of built-in container + types. + +- Issue #15839: Convert SystemErrors in super() to RuntimeErrors. + - Issue #15846: Fix SystemError which happened when using ast.parse in an exception handler on code with syntax errors.