comparison Python/pythonrun.c @ 56645:12079c3d4b77 legacy-trunk

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.
author Antoine Pitrou <solipsis@pitrou.net>
date Tue, 20 Oct 2009 21:29:37 +0000
parents 634502be8dcc
children 4468666d01c4
comparison
equal deleted inserted replaced
56642:1b602a2d81ef 56645:12079c3d4b77
15 #include "symtable.h" 15 #include "symtable.h"
16 #include "pyarena.h" 16 #include "pyarena.h"
17 #include "ast.h" 17 #include "ast.h"
18 #include "eval.h" 18 #include "eval.h"
19 #include "marshal.h" 19 #include "marshal.h"
20 #include "abstract.h"
20 21
21 #ifdef HAVE_SIGNAL_H 22 #ifdef HAVE_SIGNAL_H
22 #include <signal.h> 23 #include <signal.h>
23 #endif 24 #endif
24 25
59 PyCompilerFlags *, PyArena *); 60 PyCompilerFlags *, PyArena *);
60 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, 61 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
61 PyCompilerFlags *); 62 PyCompilerFlags *);
62 static void err_input(perrdetail *); 63 static void err_input(perrdetail *);
63 static void initsigs(void); 64 static void initsigs(void);
65 static void wait_for_thread_shutdown(void);
64 static void call_sys_exitfunc(void); 66 static void call_sys_exitfunc(void);
65 static void call_ll_exitfuncs(void); 67 static void call_ll_exitfuncs(void);
66 extern void _PyUnicode_Init(void); 68 extern void _PyUnicode_Init(void);
67 extern void _PyUnicode_Fini(void); 69 extern void _PyUnicode_Fini(void);
68 70
387 PyInterpreterState *interp; 389 PyInterpreterState *interp;
388 PyThreadState *tstate; 390 PyThreadState *tstate;
389 391
390 if (!initialized) 392 if (!initialized)
391 return; 393 return;
394
395 wait_for_thread_shutdown();
392 396
393 /* The interpreter is still entirely intact at this point, and the 397 /* The interpreter is still entirely intact at this point, and the
394 * exit funcs may be relying on that. In particular, if some thread 398 * exit funcs may be relying on that. In particular, if some thread
395 * or exit func is still waiting to do an import, the import machinery 399 * or exit func is still waiting to do an import, the import machinery
396 * expects Py_IsInitialized() to return true. So don't say the 400 * expects Py_IsInitialized() to return true. So don't say the
1664 1668
1665 #ifdef WITH_THREAD 1669 #ifdef WITH_THREAD
1666 #include "pythread.h" 1670 #include "pythread.h"
1667 #endif 1671 #endif
1668 1672
1673 /* Wait until threading._shutdown completes, provided
1674 the threading module was imported in the first place.
1675 The shutdown routine will wait until all non-daemon
1676 "threading" threads have completed. */
1677 static void
1678 wait_for_thread_shutdown(void)
1679 {
1680 #ifdef WITH_THREAD
1681 PyObject *result;
1682 PyThreadState *tstate = PyThreadState_GET();
1683 PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
1684 "threading");
1685 if (threading == NULL) {
1686 /* threading not imported */
1687 PyErr_Clear();
1688 return;
1689 }
1690 result = PyObject_CallMethod(threading, "_shutdown", "");
1691 if (result == NULL)
1692 PyErr_WriteUnraisable(threading);
1693 else
1694 Py_DECREF(result);
1695 Py_DECREF(threading);
1696 #endif
1697 }
1698
1669 #define NEXITFUNCS 32 1699 #define NEXITFUNCS 32
1670 static void (*exitfuncs[NEXITFUNCS])(void); 1700 static void (*exitfuncs[NEXITFUNCS])(void);
1671 static int nexitfuncs = 0; 1701 static int nexitfuncs = 0;
1672 1702
1673 int Py_AtExit(void (*func)(void)) 1703 int Py_AtExit(void (*func)(void))