summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2008-08-12 14:49:50 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2008-08-12 14:49:50 (GMT)
commitf91d46a17d85da323895950852093117bc21f860 (patch)
treec6a3e68cf22a6a102f9c1dc780438f0307b6588f /Objects/abstract.c
parentaa8efbf08469c3667ed22362c0e10b83ae124c0b (diff)
downloadcpython-f91d46a17d85da323895950852093117bc21f860.zip
cpython-f91d46a17d85da323895950852093117bc21f860.tar.gz
cpython-f91d46a17d85da323895950852093117bc21f860.tar.bz2
Issue #3139: Make buffer-interface thread-safe wrt. PyArg_ParseTuple,
by denying s# to parse objects that have a releasebuffer procedure, and introducing s*. More module might need to get converted to use s*.
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 5cabe58..5fb89f3 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -362,16 +362,6 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
}
-void
-PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)
-{
- if (obj->ob_type->tp_as_buffer != NULL &&
- obj->ob_type->tp_as_buffer->bf_releasebuffer != NULL) {
- (*(obj->ob_type->tp_as_buffer->bf_releasebuffer))(obj, view);
- }
-}
-
-
static int
_IsFortranContiguous(Py_buffer *view)
{
@@ -603,15 +593,15 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
- PyObject_ReleaseBuffer(dest, &view_dest);
+ PyBuffer_Release(&view_dest);
return -1;
}
if (view_dest.len < view_src.len) {
PyErr_SetString(PyExc_BufferError,
"destination is too small to receive data from source");
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return -1;
}
@@ -621,8 +611,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
PyBuffer_IsContiguous(&view_src, 'F'))) {
/* simplest copy is all that is needed */
memcpy(view_dest.buf, view_src.buf, view_src.len);
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return 0;
}
@@ -632,8 +622,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
if (indices == NULL) {
PyErr_NoMemory();
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return -1;
}
for (k=0; k<view_src.ndim;k++) {
@@ -651,8 +641,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
memcpy(dptr, sptr, view_src.itemsize);
}
PyMem_Free(indices);
- PyObject_ReleaseBuffer(dest, &view_dest);
- PyObject_ReleaseBuffer(src, &view_src);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
return 0;
}
@@ -681,7 +671,7 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
}
int
-PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
+PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
int readonly, int flags)
{
if (view == NULL) return 0;
@@ -692,6 +682,7 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
return -1;
}
+ view->obj = obj;
view->buf = buf;
view->len = len;
view->readonly = readonly;
@@ -711,6 +702,17 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
return 0;
}
+void
+PyBuffer_Release(Py_buffer *view)
+{
+ PyObject *obj = view->obj;
+ if (!obj || !Py_TYPE(obj)->tp_as_buffer || !Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
+ /* Unmanaged buffer */
+ return;
+ Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
+
+}
+
PyObject *
PyObject_Format(PyObject* obj, PyObject *format_spec)
{