Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 011bd62

Browse files
committed
Merged revisions 75570 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r75570 | antoine.pitrou | 2009-10-20 23:29:37 +0200 (mar., 20 oct. 2009) | 6 lines Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which fixes the problem of some exceptions being thrown at shutdown when the interpreter is killed. Patch by Adam Olsen. ........
1 parent 06bb674 commit 011bd62

5 files changed

Lines changed: 59 additions & 29 deletions

File tree

Lib/test/test_threading.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,28 @@ def func(frame, event, arg):
300300
self.assertFalse(rc == 2, "interpreted was blocked")
301301
self.assertTrue(rc == 0, "Unexpected error")
302302

303+
def test_join_nondaemon_on_shutdown(self):
304+
# Issue 1722344
305+
# Raising SystemExit skipped threading._shutdown
306+
import subprocess
307+
p = subprocess.Popen([sys.executable, "-c", """if 1:
308+
import threading
309+
from time import sleep
310+
311+
def child():
312+
sleep(1)
313+
# As a non-daemon thread we SHOULD wake up and nothing
314+
# should be torn down yet
315+
print("Woke up, sleep function is:", sleep)
316+
317+
threading.Thread(target=child).start()
318+
raise SystemExit
319+
"""],
320+
stdout=subprocess.PIPE,
321+
stderr=subprocess.PIPE)
322+
stdout, stderr = p.communicate()
323+
self.assertEqual(stdout, b"Woke up, sleep function is: <built-in function sleep>\n")
324+
self.assertEqual(stderr, b"")
303325

304326
def test_enumerate_after_join(self):
305327
# Try hard to trigger #1703448: a thread is still returned in

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ Kevin O'Connor
544544
Tim O'Malley
545545
Pascal Oberndoerfer
546546
Jeffrey Ollie
547+
Adam Olsen
547548
Grant Olson
548549
Piet van Oostrum
549550
Jason Orendorff

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ What's New in Python 3.2 Alpha 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which
16+
fixes the problem of some exceptions being thrown at shutdown when the
17+
interpreter is killed. Patch by Adam Olsen.
18+
1519
- Issue #7147: Remove support for compiling Python without complex number
1620
support.
1721

Modules/main.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -253,33 +253,6 @@ static int RunMainFromImporter(wchar_t *filename)
253253
}
254254

255255

256-
/* Wait until threading._shutdown completes, provided
257-
the threading module was imported in the first place.
258-
The shutdown routine will wait until all non-daemon
259-
"threading" threads have completed. */
260-
#include "abstract.h"
261-
static void
262-
WaitForThreadShutdown(void)
263-
{
264-
#ifdef WITH_THREAD
265-
PyObject *result;
266-
PyThreadState *tstate = PyThreadState_GET();
267-
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
268-
"threading");
269-
if (threading == NULL) {
270-
/* threading not imported */
271-
PyErr_Clear();
272-
return;
273-
}
274-
result = PyObject_CallMethod(threading, "_shutdown", "");
275-
if (result == NULL)
276-
PyErr_WriteUnraisable(threading);
277-
else
278-
Py_DECREF(result);
279-
Py_DECREF(threading);
280-
#endif
281-
}
282-
283256
/* Main program */
284257

285258
int
@@ -647,8 +620,6 @@ Py_Main(int argc, wchar_t **argv)
647620
sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
648621
}
649622

650-
WaitForThreadShutdown();
651-
652623
Py_Finalize();
653624

654625
#ifdef __INSURE__

Python/pythonrun.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "eval.h"
1919
#include "marshal.h"
2020
#include "osdefs.h"
21+
#include "abstract.h"
2122

2223
#ifdef HAVE_SIGNAL_H
2324
#include <signal.h>
@@ -66,6 +67,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
6667
static void err_input(perrdetail *);
6768
static void initsigs(void);
6869
static void call_py_exitfuncs(void);
70+
static void wait_for_thread_shutdown(void);
6971
static void call_ll_exitfuncs(void);
7072
extern void _PyUnicode_Init(void);
7173
extern void _PyUnicode_Fini(void);
@@ -363,6 +365,8 @@ Py_Finalize(void)
363365
if (!initialized)
364366
return;
365367

368+
wait_for_thread_shutdown();
369+
366370
/* The interpreter is still entirely intact at this point, and the
367371
* exit funcs may be relying on that. In particular, if some thread
368372
* or exit func is still waiting to do an import, the import machinery
@@ -2059,6 +2063,34 @@ call_py_exitfuncs(void)
20592063
PyErr_Clear();
20602064
}
20612065

2066+
/* Wait until threading._shutdown completes, provided
2067+
the threading module was imported in the first place.
2068+
The shutdown routine will wait until all non-daemon
2069+
"threading" threads have completed. */
2070+
static void
2071+
wait_for_thread_shutdown(void)
2072+
{
2073+
#ifdef WITH_THREAD
2074+
PyObject *result;
2075+
PyThreadState *tstate = PyThreadState_GET();
2076+
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
2077+
"threading");
2078+
if (threading == NULL) {
2079+
/* threading not imported */
2080+
PyErr_Clear();
2081+
return;
2082+
}
2083+
result = PyObject_CallMethod(threading, "_shutdown", "");
2084+
if (result == NULL) {
2085+
PyErr_WriteUnraisable(threading);
2086+
}
2087+
else {
2088+
Py_DECREF(result);
2089+
}
2090+
Py_DECREF(threading);
2091+
#endif
2092+
}
2093+
20622094
#define NEXITFUNCS 32
20632095
static void (*exitfuncs[NEXITFUNCS])(void);
20642096
static int nexitfuncs = 0;

0 commit comments

Comments
 (0)