Patch #1680961: remove sys.exitfunc and replace it with a private C API. Also, reimplement atexit in C so it can take advantage of this private API.

This commit is contained in:
Collin Winter 2007-03-21 02:57:17 +00:00
parent 450ee81b22
commit 670e692134
13 changed files with 360 additions and 204 deletions

View file

@ -361,7 +361,7 @@ PyImport_GetModuleDict(void)
/* List of names to clear in sys */
static char* sys_deletes[] = {
"path", "argv", "ps1", "ps2", "exitfunc",
"path", "argv", "ps1", "ps2",
"exc_type", "exc_value", "exc_traceback",
"last_type", "last_value", "last_traceback",
"path_hooks", "path_importer_cache", "meta_path",

View file

@ -56,7 +56,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
PyCompilerFlags *);
static void err_input(perrdetail *);
static void initsigs(void);
static void call_sys_exitfunc(void);
static void call_py_exitfuncs(void);
static void call_ll_exitfuncs(void);
extern void _PyUnicode_Init(void);
extern void _PyUnicode_Fini(void);
@ -355,7 +355,7 @@ Py_Finalize(void)
* threads created thru it, so this also protects pending imports in
* the threads created via Threading.
*/
call_sys_exitfunc();
call_py_exitfuncs();
initialized = 0;
/* Get current thread state and interpreter pointer */
@ -1557,6 +1557,23 @@ Py_FatalError(const char *msg)
#include "pythread.h"
#endif
static void (*pyexitfunc)(void) = NULL;
/* For the atexit module. */
void _Py_PyAtExit(void (*func)(void))
{
pyexitfunc = func;
}
static void
call_py_exitfuncs(void)
{
if (pyexitfunc == NULL)
return;
(*pyexitfunc)();
PyErr_Clear();
}
#define NEXITFUNCS 32
static void (*exitfuncs[NEXITFUNCS])(void);
static int nexitfuncs = 0;
@ -1569,27 +1586,6 @@ int Py_AtExit(void (*func)(void))
return 0;
}
static void
call_sys_exitfunc(void)
{
PyObject *exitfunc = PySys_GetObject("exitfunc");
if (exitfunc) {
PyObject *res;
Py_INCREF(exitfunc);
PySys_SetObject("exitfunc", (PyObject *)NULL);
res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
if (res == NULL) {
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
PySys_WriteStderr("Error in sys.exitfunc:\n");
}
PyErr_Print();
}
Py_DECREF(exitfunc);
}
}
static void
call_ll_exitfuncs(void)
{

View file

@ -897,9 +897,6 @@ excepthook -- called to handle any uncaught exception other than SystemExit\n\
To customize printing in an interactive session or to install a custom\n\
top-level exception handler, assign other functions to replace these.\n\
\n\
exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
\n\
stdin -- standard input file object; used by raw_input() and input()\n\
stdout -- standard output file object; used by print()\n\
stderr -- standard error object; used for error messages\n\