Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8470558

Browse files
committed
PyInterpreterState_New(), PyThreadState_New(): use malloc/free directly.
This appears to finish repairs for SF bug 1041645. This is a critical bugfix.
1 parent 263091e commit 8470558

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

Misc/NEWS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ Build
136136
C API
137137
-----
138138

139+
- The C API calls ``PyInterpreterState_New()`` and ``PyThreadState_New()``
140+
are two of the very few advertised as being safe to call without holding
141+
the GIL. However, this wasn't true in a debug build, as bug 1041645
142+
demonstrated. In a debug build, Python redirects the ``PyMem`` family
143+
of calls to Python's small-object allocator, to get the benefit of
144+
its extra debugging capabilities. But Python's small-object allocator
145+
isn't threadsafe, relying on the GIL to avoid the expense of doing its
146+
own locking. ``PyInterpreterState_New()`` and ``PyThreadState_New()``
147+
call the platform ``malloc()`` directly now, regardless of build type.
148+
139149
- PyLong_AsUnsignedLong[Mask] now support int objects as well.
140150

141151
- SF patch #998993: ``PyUnicode_DecodeUTF8Stateful`` and

Python/pystate.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33

44
#include "Python.h"
55

6+
/* --------------------------------------------------------------------------
7+
CAUTION
8+
9+
Always use malloc() and free() directly in this file. A number of these
10+
functions are advertised as safe to call when the GIL isn't held, and in
11+
a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging
12+
obmalloc functions. Those aren't thread-safe (they rely on the GIL to avoid
13+
the expense of doing their own locking).
14+
-------------------------------------------------------------------------- */
15+
616
#ifdef HAVE_DLOPEN
717
#ifdef HAVE_DLFCN_H
818
#include <dlfcn.h>
@@ -41,7 +51,8 @@ PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
4151
PyInterpreterState *
4252
PyInterpreterState_New(void)
4353
{
44-
PyInterpreterState *interp = PyMem_NEW(PyInterpreterState, 1);
54+
PyInterpreterState *interp = (PyInterpreterState *)
55+
malloc(sizeof(PyInterpreterState));
4556

4657
if (interp != NULL) {
4758
HEAD_INIT();
@@ -119,7 +130,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
119130
Py_FatalError("PyInterpreterState_Delete: remaining threads");
120131
*p = interp->next;
121132
HEAD_UNLOCK();
122-
PyMem_DEL(interp);
133+
free(interp);
123134
}
124135

125136

@@ -133,7 +144,8 @@ threadstate_getframe(PyThreadState *self)
133144
PyThreadState *
134145
PyThreadState_New(PyInterpreterState *interp)
135146
{
136-
PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
147+
PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
148+
137149
if (_PyThreadState_GetFrame == NULL)
138150
_PyThreadState_GetFrame = threadstate_getframe;
139151

@@ -226,7 +238,7 @@ tstate_delete_common(PyThreadState *tstate)
226238
}
227239
*p = tstate->next;
228240
HEAD_UNLOCK();
229-
PyMem_DEL(tstate);
241+
free(tstate);
230242
}
231243

232244

0 commit comments

Comments
 (0)