Bug #1566280: Explicitly invoke threading._shutdown from Py_Main,
to avoid relying on atexit. Will backport to 2.5.
This commit is contained in:
parent
769a40a1d0
commit
7b7c9d4208
|
@ -636,13 +636,11 @@ class _MainThread(Thread):
|
||||||
_active_limbo_lock.acquire()
|
_active_limbo_lock.acquire()
|
||||||
_active[_get_ident()] = self
|
_active[_get_ident()] = self
|
||||||
_active_limbo_lock.release()
|
_active_limbo_lock.release()
|
||||||
import atexit
|
|
||||||
atexit.register(self.__exitfunc)
|
|
||||||
|
|
||||||
def _set_daemon(self):
|
def _set_daemon(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __exitfunc(self):
|
def _exitfunc(self):
|
||||||
self._Thread__stop()
|
self._Thread__stop()
|
||||||
t = _pickSomeNonDaemonThread()
|
t = _pickSomeNonDaemonThread()
|
||||||
if t:
|
if t:
|
||||||
|
@ -715,9 +713,11 @@ def enumerate():
|
||||||
|
|
||||||
from thread import stack_size
|
from thread import stack_size
|
||||||
|
|
||||||
# Create the main thread object
|
# Create the main thread object,
|
||||||
|
# and make it available for the interpreter
|
||||||
|
# (Py_Main) as threading._shutdown.
|
||||||
|
|
||||||
_MainThread()
|
_shutdown = _MainThread()._exitfunc
|
||||||
|
|
||||||
# get thread-local implementation, either from the thread
|
# get thread-local implementation, either from the thread
|
||||||
# module, or from the python fallback
|
# module, or from the python fallback
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Bug #1566280: Explicitly invoke threading._shutdown from Py_Main,
|
||||||
|
to avoid relying on atexit.
|
||||||
|
|
||||||
- Bug #1590891: random.randrange don't return correct value for big number
|
- Bug #1590891: random.randrange don't return correct value for big number
|
||||||
|
|
||||||
- Patch #1586791: Better exception messages for some operations on strings,
|
- Patch #1586791: Better exception messages for some operations on strings,
|
||||||
|
|
|
@ -177,6 +177,33 @@ static int RunModule(char *module)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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()
|
||||||
|
{
|
||||||
|
#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
|
||||||
|
@ -514,6 +541,8 @@ Py_Main(int argc, char **argv)
|
||||||
/* XXX */
|
/* XXX */
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue