Index: Include/abstract.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v retrieving revision 2.46 diff -c -r2.46 abstract.h *** Include/abstract.h 25 Nov 2002 15:06:29 -0000 2.46 --- Include/abstract.h 9 Dec 2002 19:49:51 -0000 *************** *** 512,517 **** --- 512,559 ---- */ + PyAPI_FUNC(int) PyObject_AcquireLockedReadBuffer(PyObject *obj, + const void **buffer, + size_t *buffer_len); + + /* + Takes an arbitrary object which must support the locked + buffer interface and returns a pointer to a readable memory + location in buffer of size buffer_len. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurrs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(int) PyObject_AcquireLockedWriteBuffer(PyObject *obj, + void **buffer, + size_t *buffer_len); + + /* + Takes an arbitrary object which must support the locked + buffer interface and returns a pointer to a writeable memory + location in buffer of size buffer_len. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurrs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(void) PyObject_ReleaseLockedBuffer(PyObject *obj); + + /* + Releases the locked buffer acquired by a call to either + PyObject_AcquireLockedReadBuffer() or + PyObject_AcquireLockedReadBuffer(). + + It is *required* to call this function once for each call of + the PyObject_Acquire...Buffer() functions. + + */ + /* Iterators */ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); Index: Include/object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.112 diff -c -r2.112 object.h *** Include/object.h 17 Nov 2002 17:52:44 -0000 2.112 --- Include/object.h 9 Dec 2002 19:49:51 -0000 *************** *** 137,142 **** --- 137,147 ---- typedef int (*getwritebufferproc)(PyObject *, int, void **); typedef int (*getsegcountproc)(PyObject *, int *); typedef int (*getcharbufferproc)(PyObject *, int, const char **); + typedef size_t (*acquirelockedreadbufferproc)(PyObject *, const void **); + typedef size_t (*acquirelockedwritebufferproc)(PyObject *, void **); + typedef void (*releaselockedbufferproc)(PyObject *); + + typedef int (*objobjproc)(PyObject *, PyObject *); typedef int (*visitproc)(PyObject *, void *); typedef int (*traverseproc)(PyObject *, visitproc, void *); *************** *** 219,224 **** --- 224,234 ---- getwritebufferproc bf_getwritebuffer; getsegcountproc bf_getsegcount; getcharbufferproc bf_getcharbuffer; + /* Added in release 2.3 */ + /* The following require the Py_TPFLAGS_HAVE_LOCKEDBUFFER flag */ + acquirelockedreadbufferproc bf_acquirelockedreadbuffer; + acquirelockedwritebufferproc bf_acquirelockedwritebuffer; + releaselockedbufferproc bf_releaselockedbuffer; } PyBufferProcs; *************** *** 465,470 **** --- 475,485 ---- /* Objects support garbage collection (see objimp.h) */ #define Py_TPFLAGS_HAVE_GC (1L<<14) + /* PyBufferProcs contains bf_acquirelockedreadbuffer, + * bf_acquirelockedwritebuffer, and bf_releaselockedbuffer */ + + #define Py_TPFLAGS_HAVE_LOCKEDBUFFER (1L << 15) + #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_GETCHARBUFFER | \ Py_TPFLAGS_HAVE_SEQUENCE_IN | \ *************** *** 473,478 **** --- 488,494 ---- Py_TPFLAGS_HAVE_WEAKREFS | \ Py_TPFLAGS_HAVE_ITER | \ Py_TPFLAGS_HAVE_CLASS | \ + Py_TPFLAGS_HAVE_LOCKEDBUFFER | \ 0) #define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) Index: Objects/abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.110 diff -c -r2.110 abstract.c *** Objects/abstract.c 7 Dec 2002 10:05:25 -0000 2.110 --- Objects/abstract.c 9 Dec 2002 19:49:51 -0000 *************** *** 304,309 **** --- 304,386 ---- return 0; } + /* Locked buffer interface */ + + int PyObject_AcquireLockedReadBuffer(PyObject *obj, + const void **buffer, + size_t *buffer_len) + { + PyBufferProcs *pb; + const void *ptr; + size_t size; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (!PyType_HasFeature(obj->ob_type, Py_TPFLAGS_HAVE_LOCKEDBUFFER) || + pb == NULL || + pb->bf_acquirelockedreadbuffer == NULL) { + PyErr_SetString(PyExc_TypeError, + "expected a readable lockable buffer object"); + return -1; + } + size = (*pb->bf_acquirelockedreadbuffer)(obj, &ptr); + if (ptr == NULL) + return -1; + *buffer = ptr; + *buffer_len = size; + return 0; + } + + int PyObject_AcquireLockedWriteBuffer(PyObject *obj, + void **buffer, + size_t *buffer_len) + { + PyBufferProcs *pb; + void *ptr; + size_t size; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (!PyType_HasFeature(obj->ob_type, Py_TPFLAGS_HAVE_LOCKEDBUFFER) || + pb == NULL || + pb->bf_acquirelockedwritebuffer == NULL) { + PyErr_SetString(PyExc_TypeError, + "expected a writeable lockable buffer object"); + return -1; + } + size = (*pb->bf_acquirelockedwritebuffer)(obj, &ptr); + if (ptr == NULL) + return -1; + *buffer = ptr; + *buffer_len = size; + return 0; + } + + void PyObject_ReleaseLockedBuffer(PyObject *obj) + { + PyBufferProcs *pb; + + if (obj == NULL) { + null_error(); + return; + } + pb = obj->ob_type->tp_as_buffer; + if (pb == NULL) + return; + if (!PyType_HasFeature(obj->ob_type, Py_TPFLAGS_HAVE_LOCKEDBUFFER)) + return; + if (pb->bf_releaselockedbuffer) + (*pb->bf_releaselockedbuffer)(obj); + } + + + /* Operations on numbers */ int