]> granicus.if.org Git - python/commitdiff
Issue #13992: The trashcan mechanism is now thread-safe. This eliminates
authorAntoine Pitrou <solipsis@pitrou.net>
Wed, 5 Sep 2012 23:17:42 +0000 (01:17 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Wed, 5 Sep 2012 23:17:42 +0000 (01:17 +0200)
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.

1  2 
Include/object.h
Include/pystate.h
Lib/test/test_gc.py
Misc/NEWS
Objects/object.c
Objects/typeobject.c
Python/pystate.c

index 709a9fff13834813778684c6d614d5192869e388,6120ab813c4995041db42790238a98254fbfabfd..387cadb4e4793be677bb6808d04f3af5b7750b10
@@@ -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.
  */
  
 -   Kept for binary compatibility of extensions. */
+ /* This is the old private API, invoked by the macros before 3.2.4.
++   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
Simple merge
index d35f9ed762c41e77954863a9d967a0457aaf2ad1,e1c124d160fb7945da9994a5c39a0dcd385a6722..c59b72eacf87fa81cdc328d2672b0311231e9293
@@@ -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 aaf3aef8706d436674e2f473c49407357099c348,a1d35a4f1d323423edaf0beadc595d1ae7851e04..8046b7bf458bde98817498aa3ada357d17ce23b2
+++ 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.
  
Simple merge
Simple merge
Simple merge