Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit afbf1fa

Browse filesBrowse files
authored
Merge branch 'main' into 132322-shutil-pathlib-return
2 parents 5cbf6e6 + b5bf8c8 commit afbf1fa
Copy full SHA for afbf1fa

File tree

Expand file treeCollapse file tree

1 file changed

+72
-21
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+72
-21
lines changed

‎Modules/_interpretersmodule.c

Copy file name to clipboardExpand all lines: Modules/_interpretersmodule.c
+72-21Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,41 +76,60 @@ is_running_main(PyInterpreterState *interp)
7676
// XXX Release when the original interpreter is destroyed.
7777

7878
typedef struct {
79-
PyObject_HEAD
79+
PyObject base;
8080
Py_buffer *view;
8181
int64_t interpid;
8282
} XIBufferViewObject;
8383

8484
#define XIBufferViewObject_CAST(op) ((XIBufferViewObject *)(op))
8585

8686
static PyObject *
87-
xibufferview_from_xid(PyTypeObject *cls, _PyXIData_t *data)
87+
xibufferview_from_buffer(PyTypeObject *cls, Py_buffer *view, int64_t interpid)
8888
{
89-
assert(_PyXIData_DATA(data) != NULL);
90-
assert(_PyXIData_OBJ(data) == NULL);
91-
assert(_PyXIData_INTERPID(data) >= 0);
89+
assert(interpid >= 0);
90+
91+
Py_buffer *copied = PyMem_RawMalloc(sizeof(Py_buffer));
92+
if (copied == NULL) {
93+
return NULL;
94+
}
95+
/* This steals the view->obj reference */
96+
*copied = *view;
97+
9298
XIBufferViewObject *self = PyObject_Malloc(sizeof(XIBufferViewObject));
9399
if (self == NULL) {
100+
PyMem_RawFree(copied);
94101
return NULL;
95102
}
96-
PyObject_Init((PyObject *)self, cls);
97-
self->view = (Py_buffer *)_PyXIData_DATA(data);
98-
self->interpid = _PyXIData_INTERPID(data);
103+
PyObject_Init(&self->base, cls);
104+
*self = (XIBufferViewObject){
105+
.base = self->base,
106+
.view = copied,
107+
.interpid = interpid,
108+
};
99109
return (PyObject *)self;
100110
}
101111

102112
static void
103113
xibufferview_dealloc(PyObject *op)
104114
{
105115
XIBufferViewObject *self = XIBufferViewObject_CAST(op);
106-
PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interpid);
107-
/* If the interpreter is no longer alive then we have problems,
108-
since other objects may be using the buffer still. */
109-
assert(interp != NULL);
110116

111-
if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp, self->view) < 0) {
112-
// XXX Emit a warning?
113-
PyErr_Clear();
117+
if (self->view != NULL) {
118+
PyInterpreterState *interp =
119+
_PyInterpreterState_LookUpID(self->interpid);
120+
if (interp == NULL) {
121+
/* The interpreter is no longer alive. */
122+
PyErr_Clear();
123+
PyMem_RawFree(self->view);
124+
}
125+
else {
126+
if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp,
127+
self->view) < 0)
128+
{
129+
// XXX Emit a warning?
130+
PyErr_Clear();
131+
}
132+
}
114133
}
115134

116135
PyTypeObject *tp = Py_TYPE(self);
@@ -155,32 +174,64 @@ static PyType_Spec XIBufferViewType_spec = {
155174

156175
static PyTypeObject * _get_current_xibufferview_type(void);
157176

177+
178+
struct xibuffer {
179+
Py_buffer view;
180+
int used;
181+
};
182+
158183
static PyObject *
159184
_memoryview_from_xid(_PyXIData_t *data)
160185
{
186+
assert(_PyXIData_DATA(data) != NULL);
187+
assert(_PyXIData_OBJ(data) == NULL);
188+
assert(_PyXIData_INTERPID(data) >= 0);
189+
struct xibuffer *view = (struct xibuffer *)_PyXIData_DATA(data);
190+
assert(!view->used);
191+
161192
PyTypeObject *cls = _get_current_xibufferview_type();
162193
if (cls == NULL) {
163194
return NULL;
164195
}
165-
PyObject *obj = xibufferview_from_xid(cls, data);
196+
197+
PyObject *obj = xibufferview_from_buffer(
198+
cls, &view->view, _PyXIData_INTERPID(data));
166199
if (obj == NULL) {
167200
return NULL;
168201
}
169-
return PyMemoryView_FromObject(obj);
202+
PyObject *res = PyMemoryView_FromObject(obj);
203+
if (res == NULL) {
204+
Py_DECREF(obj);
205+
return NULL;
206+
}
207+
view->used = 1;
208+
return res;
209+
}
210+
211+
static void
212+
_pybuffer_shared_free(void* data)
213+
{
214+
struct xibuffer *view = (struct xibuffer *)data;
215+
if (!view->used) {
216+
PyBuffer_Release(&view->view);
217+
}
218+
PyMem_RawFree(data);
170219
}
171220

172221
static int
173-
_memoryview_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
222+
_pybuffer_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
174223
{
175-
Py_buffer *view = PyMem_RawMalloc(sizeof(Py_buffer));
224+
struct xibuffer *view = PyMem_RawMalloc(sizeof(struct xibuffer));
176225
if (view == NULL) {
177226
return -1;
178227
}
179-
if (PyObject_GetBuffer(obj, view, PyBUF_FULL_RO) < 0) {
228+
view->used = 0;
229+
if (PyObject_GetBuffer(obj, &view->view, PyBUF_FULL_RO) < 0) {
180230
PyMem_RawFree(view);
181231
return -1;
182232
}
183233
_PyXIData_Init(data, tstate->interp, view, NULL, _memoryview_from_xid);
234+
data->free = _pybuffer_shared_free;
184235
return 0;
185236
}
186237

@@ -201,7 +252,7 @@ register_memoryview_xid(PyObject *mod, PyTypeObject **p_state)
201252
*p_state = cls;
202253

203254
// Register XID for the builtin memoryview type.
204-
if (ensure_xid_class(&PyMemoryView_Type, _memoryview_shared) < 0) {
255+
if (ensure_xid_class(&PyMemoryView_Type, _pybuffer_shared) < 0) {
205256
return -1;
206257
}
207258
// We don't ever bother un-registering memoryview.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.