Skip to content

Commit 4a8bcdf

Browse files
authored
bpo-16500: Use register_at_fork() in the threading module (#1843)
* bpo-16500: Use register_at_fork() in the threading module * Update comment at top of _after_fork()
1 parent 0aa0a06 commit 4a8bcdf

File tree

2 files changed

+9
-22
lines changed

2 files changed

+9
-22
lines changed

Lib/threading.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Thread module emulating a subset of Java's threading model."""
22

3+
import os as _os
34
import sys as _sys
45
import _thread
56

@@ -943,6 +944,7 @@ def _bootstrap_inner(self):
943944
exc_tb.tb_frame.f_code.co_name)), file=self._stderr)
944945
exc_tb = exc_tb.tb_next
945946
print(("%s: %s" % (exc_type, exc_value)), file=self._stderr)
947+
self._stderr.flush()
946948
# Make sure that exc_tb gets deleted since it is a memory
947949
# hog; deleting everything else is just for thoroughness
948950
finally:
@@ -1319,10 +1321,9 @@ def main_thread():
13191321

13201322

13211323
def _after_fork():
1322-
# This function is called by Python/ceval.c:PyEval_ReInitThreads which
1323-
# is called from PyOS_AfterFork_Child. Here we cleanup threading module
1324-
# state that should not exist after a fork.
1325-
1324+
"""
1325+
Cleanup threading module state that should not exist after a fork.
1326+
"""
13261327
# Reset _active_limbo_lock, in case we forked while the lock was held
13271328
# by another (non-forked) thread. http://bugs.python.org/issue874900
13281329
global _active_limbo_lock, _main_thread
@@ -1356,3 +1357,7 @@ def _after_fork():
13561357
_active.clear()
13571358
_active.update(new_active)
13581359
assert len(_active) == 1
1360+
1361+
1362+
if hasattr(_os, "fork"):
1363+
_os.register_at_fork(_after_fork, when="child")

Python/ceval.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,6 @@ PyEval_ReleaseThread(PyThreadState *tstate)
240240
void
241241
PyEval_ReInitThreads(void)
242242
{
243-
_Py_IDENTIFIER(_after_fork);
244-
PyObject *threading, *result;
245243
PyThreadState *current_tstate = PyThreadState_GET();
246244

247245
if (!gil_created())
@@ -251,22 +249,6 @@ PyEval_ReInitThreads(void)
251249
take_gil(current_tstate);
252250
main_thread = PyThread_get_thread_ident();
253251

254-
/* Update the threading module with the new state.
255-
*/
256-
threading = PyMapping_GetItemString(current_tstate->interp->modules,
257-
"threading");
258-
if (threading == NULL) {
259-
/* threading not imported */
260-
PyErr_Clear();
261-
return;
262-
}
263-
result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL);
264-
if (result == NULL)
265-
PyErr_WriteUnraisable(threading);
266-
else
267-
Py_DECREF(result);
268-
Py_DECREF(threading);
269-
270252
/* Destroy all threads except the current one */
271253
_PyThreadState_DeleteExcept(current_tstate);
272254
}

0 commit comments

Comments
 (0)