summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2013-09-09 12:12:21 (GMT)
committerLarry Hastings <larry@hastings.org>2013-09-09 12:12:21 (GMT)
commit8568f66daf088cf235a42288621fb4770ac48199 (patch)
tree3db459417e7c4b112b03d59661057f09ff058d07 /Include
parent60560b18d29a917e64d88d47c5533743001f0787 (diff)
parent23543ebd8676384c1c5e28f7a1496777a57479d5 (diff)
downloadcpython-8568f66daf088cf235a42288621fb4770ac48199.zip
cpython-8568f66daf088cf235a42288621fb4770ac48199.tar.gz
cpython-8568f66daf088cf235a42288621fb4770ac48199.tar.bz2
Merge.
Diffstat (limited to 'Include')
-rw-r--r--Include/pystate.h26
-rw-r--r--Include/setobject.h1
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