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

Skip to content

Commit 423be95

Browse files
committed
Merged revisions 65654 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r65654 | martin.v.loewis | 2008-08-12 16:49:50 +0200 (Tue, 12 Aug 2008) | 6 lines 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*. ........
1 parent 688356f commit 423be95

32 files changed

Lines changed: 720 additions & 389 deletions

Doc/c-api/arg.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ variable(s) whose address should be passed.
4040
other read-buffer compatible objects pass back a reference to the raw internal
4141
data representation.
4242

43+
``s*`` (string, Unicode, or any buffer compatible object) [Py_buffer \*]
44+
Similar to ``s#``, this code fills a Py_buffer structure provided by the caller.
45+
The buffer gets locked, so that the caller can subsequently use the buffer even
46+
inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is responsible for calling
47+
``PyBuffer_Release`` with the structure after it has processed the data.
48+
4349
``y`` (bytes object) [const char \*]
4450
This variant on ``s`` convert a Python bytes object to a C pointer to a
4551
character string. The bytes object must not contain embedded NUL bytes; if it
@@ -49,13 +55,19 @@ variable(s) whose address should be passed.
4955
This variant on ``s#`` stores into two C variables, the first one a pointer to a
5056
character string, the second one its length. This only accepts bytes objects.
5157

58+
``y*`` (bytes object) [Py_buffer \*]
59+
This is to ``s*`` as ``y`` is to ``s``.
60+
5261
``z`` (string or ``None``) [const char \*]
5362
Like ``s``, but the Python object may also be ``None``, in which case the C
5463
pointer is set to *NULL*.
5564

5665
``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int]
5766
This is to ``s#`` as ``z`` is to ``s``.
5867

68+
``z*`` (string or ``None`` or any buffer compatible object) [Py_buffer*]
69+
This is to ``s*`` as ``z`` is to ``s``.
70+
5971
``u`` (Unicode object) [Py_UNICODE \*]
6072
Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of
6173
16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide
@@ -244,6 +256,9 @@ variable(s) whose address should be passed.
244256
single-segment buffer objects are accepted; :exc:`TypeError` is raised for all
245257
others.
246258

259+
``w*`` (read-write byte-oriented buffer) [Py_buffer \*]
260+
This is to ``w`` what ``s*`` is to ``s``.
261+
247262
``(items)`` (tuple) [*matching-items*]
248263
The object must be a Python sequence whose length is the number of format units
249264
in *items*. The C arguments must correspond to the individual format units in

Doc/whatsnew/2.6.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ about the object's memory representation. Objects
10641064
can use this operation to lock memory in place
10651065
while an external caller could be modifying the contents,
10661066
so there's a corresponding
1067-
``PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)`` to
1067+
``PyBuffer_Release(Py_buffer *view)`` to
10681068
indicate that the external caller is done.
10691069

10701070
The **flags** argument to :cfunc:`PyObject_GetBuffer` specifies
@@ -2841,7 +2841,7 @@ Changes to Python's build process and to the C API include:
28412841

28422842
* The new buffer interface, previously described in
28432843
`the PEP 3118 section <#pep-3118-revised-buffer-protocol>`__,
2844-
adds :cfunc:`PyObject_GetBuffer` and :cfunc:`PyObject_ReleaseBuffer`,
2844+
adds :cfunc:`PyObject_GetBuffer` and :cfunc:`PyBuffer_Release`,
28452845
as well as a few other functions.
28462846

28472847
* Python's use of the C stdio library is now thread-safe, or at least

Include/abstract.h

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -526,24 +526,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
526526
*/
527527

528528

529-
PyAPI_FUNC(void) PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view);
530-
531-
532-
/* C-API version of the releasebuffer function call. It
533-
checks to make sure the object has the required function
534-
pointer and issues the call. The obj must have the buffer
535-
interface or this function will cause a segfault (i.e. it
536-
is assumed to be called only after a corresponding
537-
getbuffer which already verified the existence of the
538-
tp_as_buffer pointer).
539-
540-
Returns 0 on success and -1 (with an error raised) on
541-
failure. This function always succeeds (as a NO-OP) if
542-
there is no releasebuffer function for the object so that
543-
it can always be called when the consumer is done with the
544-
buffer
545-
*/
546-
547529
PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
548530

549531
/* Get the memory area pointed to by the indices for the buffer given.
@@ -600,7 +582,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
600582
per element.
601583
*/
602584

603-
PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, void *buf,
585+
PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
604586
Py_ssize_t len, int readonly,
605587
int flags);
606588

@@ -610,6 +592,10 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
610592
and -1 (with raising an error) on error.
611593
*/
612594

595+
PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
596+
597+
/* Releases a Py_buffer obtained from getbuffer ParseTuple's s*.
598+
*/
613599

614600
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject* obj,
615601
PyObject *format_spec);

Include/object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
142142

143143
/* buffer interface */
144144
typedef struct bufferinfo {
145-
void *buf;
145+
void *buf;
146+
PyObject *obj; /* borrowed reference */
146147
Py_ssize_t len;
147148
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
148149
pointed to by strides in simple case.*/

Lib/test/test_sys.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ def get_gen(): yield 1
550550
check(32768*32768-1, size(vh) + 2*self.H)
551551
check(32768*32768, size(vh) + 3*self.H)
552552
# memory
553-
check(memoryview(b''), size(h + 'P P2P2i5P'))
553+
check(memoryview(b''), size(h + 'P PP2P2i5P'))
554554
# module
555555
check(unittest, size(h + '3P'))
556556
# None

Modules/_bsddb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static void free_dbt(DBT *dbt)
288288
static void free_buf_view(PyObject *obj, Py_buffer *view)
289289
{
290290
if (view) {
291-
PyObject_ReleaseBuffer(obj, view);
291+
PyBuffer_Release(view);
292292
PyMem_Free(view);
293293
}
294294
}
@@ -319,7 +319,7 @@ static Py_buffer * _malloc_view(PyObject *obj)
319319
if (view->ndim > 1) {
320320
PyErr_SetString(PyExc_BufferError,
321321
"buffers must be single dimension");
322-
PyObject_ReleaseBuffer(obj, view);
322+
PyBuffer_Release(view);
323323
PyMem_Free(view);
324324
return NULL;
325325
}

0 commit comments

Comments
 (0)