Kaydet (Commit) cefb316e authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Merged revisions 75571,75576-75577 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r75571 | antoine.pitrou | 2009-10-20 23:52:47 +0200 (mar., 20 oct. 2009) | 11 lines

  Merged revisions 75570 via svnmerge from
  svn+ssh://pythondev@svn.python.org/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.
  ........
................
  r75576 | antoine.pitrou | 2009-10-21 00:02:29 +0200 (mer., 21 oct. 2009) | 10 lines

  Merged revisions 75574 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r75574 | antoine.pitrou | 2009-10-20 23:59:25 +0200 (mar., 20 oct. 2009) | 4 lines

    Test wouldn't work in debug mode.
    We probably need a function in test_support to handle this.
  ........
................
  r75577 | antoine.pitrou | 2009-10-21 00:05:38 +0200 (mer., 21 oct. 2009) | 3 lines

  Another futile error in the previous commit :-(
................
üst 2d4fce2d
...@@ -286,6 +286,29 @@ class ThreadTests(unittest.TestCase): ...@@ -286,6 +286,29 @@ class ThreadTests(unittest.TestCase):
self.assertFalse(rc == 2, "interpreted was blocked") self.assertFalse(rc == 2, "interpreted was blocked")
self.assertTrue(rc == 0, "Unexpected error") self.assertTrue(rc == 0, "Unexpected error")
def test_join_nondaemon_on_shutdown(self):
# Issue 1722344
# Raising SystemExit skipped threading._shutdown
import subprocess
p = subprocess.Popen([sys.executable, "-c", """if 1:
import threading
from time import sleep
def child():
sleep(1)
# As a non-daemon thread we SHOULD wake up and nothing
# should be torn down yet
print("Woke up, sleep function is:", sleep)
threading.Thread(target=child).start()
raise SystemExit
"""],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
self.assertEqual(stdout, b"Woke up, sleep function is: <built-in function sleep>\n")
stderr = re.sub(br"^\[\d+ refs\]", b"", stderr, re.MULTILINE).strip()
self.assertEqual(stderr, b"")
def test_enumerate_after_join(self): def test_enumerate_after_join(self):
# Try hard to trigger #1703448: a thread is still returned in # Try hard to trigger #1703448: a thread is still returned in
......
...@@ -539,6 +539,7 @@ Kevin O'Connor ...@@ -539,6 +539,7 @@ Kevin O'Connor
Tim O'Malley Tim O'Malley
Pascal Oberndoerfer Pascal Oberndoerfer
Jeffrey Ollie Jeffrey Ollie
Adam Olsen
Grant Olson Grant Olson
Piet van Oostrum Piet van Oostrum
Jason Orendorff Jason Orendorff
......
...@@ -12,6 +12,10 @@ What's New in Python 3.1.2? ...@@ -12,6 +12,10 @@ What's New in Python 3.1.2?
Core and Builtins Core and Builtins
----------------- -----------------
- 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.
- Issue #7065: Fix a crash in bytes.maketrans and bytearray.maketrans when - Issue #7065: Fix a crash in bytes.maketrans and bytearray.maketrans when
using byte values greater than 127. Patch by Derk Drukker. using byte values greater than 127. Patch by Derk Drukker.
......
...@@ -253,33 +253,6 @@ static int RunMainFromImporter(wchar_t *filename) ...@@ -253,33 +253,6 @@ static int RunMainFromImporter(wchar_t *filename)
} }
/* Wait until threading._shutdown completes, provided
the threading module was imported in the first place.
The shutdown routine will wait until all non-daemon
"threading" threads have completed. */
#include "abstract.h"
static void
WaitForThreadShutdown(void)
{
#ifdef WITH_THREAD
PyObject *result;
PyThreadState *tstate = PyThreadState_GET();
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
"threading");
if (threading == NULL) {
/* threading not imported */
PyErr_Clear();
return;
}
result = PyObject_CallMethod(threading, "_shutdown", "");
if (result == NULL)
PyErr_WriteUnraisable(threading);
else
Py_DECREF(result);
Py_DECREF(threading);
#endif
}
/* Main program */ /* Main program */
int int
...@@ -647,8 +620,6 @@ Py_Main(int argc, wchar_t **argv) ...@@ -647,8 +620,6 @@ Py_Main(int argc, wchar_t **argv)
sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0; sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
} }
WaitForThreadShutdown();
Py_Finalize(); Py_Finalize();
#ifdef __INSURE__ #ifdef __INSURE__
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "eval.h" #include "eval.h"
#include "marshal.h" #include "marshal.h"
#include "osdefs.h" #include "osdefs.h"
#include "abstract.h"
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
#include <signal.h> #include <signal.h>
...@@ -66,6 +67,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, ...@@ -66,6 +67,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
static void err_input(perrdetail *); static void err_input(perrdetail *);
static void initsigs(void); static void initsigs(void);
static void call_py_exitfuncs(void); static void call_py_exitfuncs(void);
static void wait_for_thread_shutdown(void);
static void call_ll_exitfuncs(void); static void call_ll_exitfuncs(void);
extern void _PyUnicode_Init(void); extern void _PyUnicode_Init(void);
extern void _PyUnicode_Fini(void); extern void _PyUnicode_Fini(void);
...@@ -363,6 +365,8 @@ Py_Finalize(void) ...@@ -363,6 +365,8 @@ Py_Finalize(void)
if (!initialized) if (!initialized)
return; return;
wait_for_thread_shutdown();
/* The interpreter is still entirely intact at this point, and the /* The interpreter is still entirely intact at this point, and the
* exit funcs may be relying on that. In particular, if some thread * exit funcs may be relying on that. In particular, if some thread
* or exit func is still waiting to do an import, the import machinery * or exit func is still waiting to do an import, the import machinery
...@@ -2059,6 +2063,34 @@ call_py_exitfuncs(void) ...@@ -2059,6 +2063,34 @@ call_py_exitfuncs(void)
PyErr_Clear(); PyErr_Clear();
} }
/* Wait until threading._shutdown completes, provided
the threading module was imported in the first place.
The shutdown routine will wait until all non-daemon
"threading" threads have completed. */
static void
wait_for_thread_shutdown(void)
{
#ifdef WITH_THREAD
PyObject *result;
PyThreadState *tstate = PyThreadState_GET();
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
"threading");
if (threading == NULL) {
/* threading not imported */
PyErr_Clear();
return;
}
result = PyObject_CallMethod(threading, "_shutdown", "");
if (result == NULL) {
PyErr_WriteUnraisable(threading);
}
else {
Py_DECREF(result);
}
Py_DECREF(threading);
#endif
}
#define NEXITFUNCS 32 #define NEXITFUNCS 32
static void (*exitfuncs[NEXITFUNCS])(void); static void (*exitfuncs[NEXITFUNCS])(void);
static int nexitfuncs = 0; static int nexitfuncs = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment