Commit 9aece752 authored by Antoine Pitrou's avatar Antoine Pitrou

Merged revisions 75570,75574,75624 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.
........
  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.
........
  r75624 | antoine.pitrou | 2009-10-23 14:01:13 +0200 (ven., 23 oct. 2009) | 3 lines

  Fix Windows buildbot failure
........
parent f75774b5
...@@ -284,6 +284,30 @@ class ThreadTests(unittest.TestCase): ...@@ -284,6 +284,30 @@ class ThreadTests(unittest.TestCase):
self.failIf(rc == 2, "interpreted was blocked") self.failIf(rc == 2, "interpreted was blocked")
self.failUnless(rc == 0, "Unexpected error") self.failUnless(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.strip(),
"Woke up, sleep function is: <built-in function sleep>")
stderr = re.sub(r"^\[\d+ refs\]", "", stderr, re.MULTILINE).strip()
self.assertEqual(stderr, "")
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
......
...@@ -517,6 +517,7 @@ Kevin O'Connor ...@@ -517,6 +517,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
......
...@@ -4,6 +4,22 @@ Python News ...@@ -4,6 +4,22 @@ Python News
(editors: check NEWS.help for information about editing NEWS using ReST.) (editors: check NEWS.help for information about editing NEWS using ReST.)
What's New in Python 2.6.5
==========================
*Release date: XX-XXX-20XX*
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.
Library
-------
What's New in Python 2.6.4 final? What's New in Python 2.6.4 final?
================================= =================================
......
...@@ -222,33 +222,6 @@ static int RunMainFromImporter(char *filename) ...@@ -222,33 +222,6 @@ static int RunMainFromImporter(char *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
...@@ -620,8 +593,6 @@ Py_Main(int argc, char **argv) ...@@ -620,8 +593,6 @@ Py_Main(int argc, char **argv)
sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0; sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
} }
WaitForThreadShutdown();
Py_Finalize(); Py_Finalize();
#ifdef RISCOS #ifdef RISCOS
if (Py_RISCOSWimpFlag) if (Py_RISCOSWimpFlag)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "ast.h" #include "ast.h"
#include "eval.h" #include "eval.h"
#include "marshal.h" #include "marshal.h"
#include "abstract.h"
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
#include <signal.h> #include <signal.h>
...@@ -61,6 +62,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, ...@@ -61,6 +62,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
PyCompilerFlags *); PyCompilerFlags *);
static void err_input(perrdetail *); static void err_input(perrdetail *);
static void initsigs(void); static void initsigs(void);
static void wait_for_thread_shutdown(void);
static void call_sys_exitfunc(void); static void call_sys_exitfunc(void);
static void call_ll_exitfuncs(void); static void call_ll_exitfuncs(void);
extern void _PyUnicode_Init(void); extern void _PyUnicode_Init(void);
...@@ -387,6 +389,8 @@ Py_Finalize(void) ...@@ -387,6 +389,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
...@@ -1663,6 +1667,32 @@ Py_FatalError(const char *msg) ...@@ -1663,6 +1667,32 @@ Py_FatalError(const char *msg)
#include "pythread.h" #include "pythread.h"
#endif #endif
/* 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