diff options
author | Larry Hastings <larry@hastings.org> | 2013-09-09 12:12:21 (GMT) |
---|---|---|
committer | Larry Hastings <larry@hastings.org> | 2013-09-09 12:12:21 (GMT) |
commit | 8568f66daf088cf235a42288621fb4770ac48199 (patch) | |
tree | 3db459417e7c4b112b03d59661057f09ff058d07 /Include | |
parent | 60560b18d29a917e64d88d47c5533743001f0787 (diff) | |
parent | 23543ebd8676384c1c5e28f7a1496777a57479d5 (diff) | |
download | cpython-8568f66daf088cf235a42288621fb4770ac48199.zip cpython-8568f66daf088cf235a42288621fb4770ac48199.tar.gz cpython-8568f66daf088cf235a42288621fb4770ac48199.tar.bz2 |
Merge.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/pystate.h | 26 | ||||
-rw-r--r-- | Include/setobject.h | 1 |
2 files changed, 26 insertions, 1 deletions
diff --git a/Include/pystate.h b/Include/pystate.h index e41fe4c..ddc6892 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -118,6 +118,32 @@ typedef struct _ts { int trash_delete_nesting; PyObject *trash_delete_later; + /* Called when a thread state is deleted normally, but not when it + * is destroyed after fork(). + * Pain: to prevent rare but fatal shutdown errors (issue 18808), + * Thread.join() must wait for the join'ed thread's tstate to be unlinked + * from the tstate chain. That happens at the end of a thread's life, + * in pystate.c. + * The obvious way doesn't quite work: create a lock which the tstate + * unlinking code releases, and have Thread.join() wait to acquire that + * lock. The problem is that we _are_ at the end of the thread's life: + * if the thread holds the last reference to the lock, decref'ing the + * lock will delete the lock, and that may trigger arbitrary Python code + * if there's a weakref, with a callback, to the lock. But by this time + * _PyThreadState_Current is already NULL, so only the simplest of C code + * can be allowed to run (in particular it must not be possible to + * release the GIL). + * So instead of holding the lock directly, the tstate holds a weakref to + * the lock: that's the value of on_delete_data below. Decref'ing a + * weakref is harmless. + * on_delete points to _threadmodule.c's static release_sentinel() function. + * After the tstate is unlinked, release_sentinel is called with the + * weakref-to-lock (on_delete_data) argument, and release_sentinel releases + * the indirectly held lock. + */ + void (*on_delete)(void *); + void *on_delete_data; + /* XXX signal handlers should also be here */ } PyThreadState; diff --git a/Include/setobject.h b/Include/setobject.h index f377a73..ae3f556 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -105,7 +105,6 @@ PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); PyAPI_FUNC(int) PySet_ClearFreeList(void); -PyAPI_FUNC(void) _PySet_DebugMallocStats(FILE *out); #endif #ifdef __cplusplus |