Skip to content

Commit 7d71fb8

Browse files
committed
Little fixes:
* make some module variables static to prevent name pollution * Add some comments to clarify what's going on and some XXXs to address * Add a space after "for" before ( * exc_value and tb can be NULL in some cases * Get working on Windows (I think)
1 parent 670e692 commit 7d71fb8

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

Modules/atexitmodule.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ typedef struct {
1717
PyObject *kwargs;
1818
} atexit_callback;
1919

20-
atexit_callback **atexit_callbacks;
21-
int ncallbacks = 0;
22-
int callback_len = 32;
20+
static atexit_callback **atexit_callbacks;
21+
static int ncallbacks = 0;
22+
static int callback_len = 32;
2323

2424
/* Installed into pythonrun.c's atexit mechanism */
2525

@@ -33,7 +33,7 @@ atexit_callfuncs(void)
3333
if (ncallbacks == 0)
3434
return;
3535

36-
for(i = ncallbacks - 1; i >= 0; i--)
36+
for (i = ncallbacks - 1; i >= 0; i--)
3737
{
3838
cb = atexit_callbacks[i];
3939
if (cb == NULL)
@@ -42,10 +42,12 @@ atexit_callfuncs(void)
4242
r = PyObject_Call(cb->func, cb->args, cb->kwargs);
4343
Py_XDECREF(r);
4444
if (r == NULL) {
45+
/* Maintain the last exception, but don't leak if there are
46+
multiple exceptions. */
4547
if (exc_type) {
4648
Py_DECREF(exc_type);
47-
Py_DECREF(exc_value);
48-
Py_DECREF(exc_tb);
49+
Py_XDECREF(exc_value);
50+
Py_XDECREF(exc_tb);
4951
}
5052
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
5153
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
@@ -92,6 +94,8 @@ atexit_register(PyObject *self, PyObject *args, PyObject *kwargs)
9294

9395
if (ncallbacks >= callback_len) {
9496
callback_len += 16;
97+
/* XXX(nnorwitz): this leaks if realloc() fails. It also
98+
doesn't verify realloc() returns a valid (non-NULL) pointer. */
9599
atexit_callbacks = PyMem_Realloc(atexit_callbacks,
96100
sizeof(atexit_callback*) * callback_len);
97101

@@ -145,7 +149,7 @@ atexit_clear(PyObject *self)
145149
atexit_callback *cb;
146150
int i;
147151

148-
for(i = 0; i < ncallbacks; i++)
152+
for (i = 0; i < ncallbacks; i++)
149153
{
150154
cb = atexit_callbacks[i];
151155
if (cb == NULL)
@@ -163,7 +167,7 @@ atexit_unregister(PyObject *self, PyObject *func)
163167
atexit_callback *cb;
164168
int i, eq;
165169

166-
for(i = 0; i < ncallbacks; i++)
170+
for (i = 0; i < ncallbacks; i++)
167171
{
168172
cb = atexit_callbacks[i];
169173
if (cb == NULL)
@@ -213,5 +217,8 @@ initatexit(void)
213217
if (m == NULL)
214218
return;
215219

220+
/* XXX(nnorwitz): probably best to register a callback that will free
221+
atexit_callbacks, otherwise valgrind will report memory leaks.
222+
Need to call atexit_clear() first. */
216223
_Py_PyAtExit(atexit_callfuncs);
217224
}

PC/config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ extern void init_subprocess(void);
6868
extern void init_lsprof(void);
6969
extern void init_ast(void);
7070
extern void init_types(void);
71+
extern void initatexit(void);
7172

7273
/* tools/freeze/makeconfig.py marker for additional "extern" */
7374
/* -- ADDMODULE MARKER 1 -- */
@@ -79,6 +80,7 @@ struct _inittab _PyImport_Inittab[] = {
7980

8081
{"array", initarray},
8182
{"_ast", init_ast},
83+
{"atexit", initatexit},
8284
#ifdef MS_WINDOWS
8385
#ifndef MS_WIN64
8486
{"audioop", initaudioop},

0 commit comments

Comments
 (0)