Travis Oliphant wrote: > This should be clarified in the PEP. Can you take a stab at it?
Would this work? Stefan
Index: pep-3118.txt =================================================================== --- pep-3118.txt (Revision 63861) +++ pep-3118.txt (Arbeitskopie) @@ -153,10 +153,8 @@ This function returns ``0`` on success and ``-1`` on failure (and raises an error). The first variable is the "exporting" object. The second -argument is the address to a bufferinfo structure. If view is ``NULL``, -then no information is returned but a lock on the memory is still -obtained. In this case, the corresponding releasebuffer should also -be called with ``NULL``. +argument is the address to a bufferinfo structure. Both arguments must +never be NULL. The third argument indicates what kind of buffer the consumer is prepared to deal with and therefore what kind of buffer the exporter @@ -178,6 +176,19 @@ structure (with defaults or NULLs if nothing else is requested). The PyBuffer_FillInfo function can be used for simple cases. +The second function is called to release the Py_buffer view, which may +allow the provider to clean up the buffer itself:: + + typedef void (*releasebufferproc)(Py_buffer *view) + +Any existing lock on the buffer will be released by this call. The +Py_buffer struct will be invalidated and can no longer be used by the +caller. + + +Access flags +------------ + Some flags are useful for requesting a specific kind of memory segment, while others indicate to the exporter what kind of information the consumer can deal with. If certain information is not @@ -185,14 +196,6 @@ without that information, then a ``PyErr_BufferError`` should be raised. -``PyBUF_SIMPLE`` - - This is the default flag state (0). The returned buffer may or may - not have writable memory. The format will be assumed to be - unsigned bytes . This is a "stand-alone" flag constant. It never - needs to be \|'d to the others. The exporter will raise an error if - it cannot provide such a contiguous buffer of bytes. - ``PyBUF_WRITABLE`` The returned buffer must be writable. If it is not writable, @@ -221,6 +224,54 @@ necessary (especially the exclusive write lock) as it makes the object unable to share its memory until the lock is released. + The ``PyBUF_LOCK`` flag is the only case where a Py_buffer struct + with an initialised ``buf`` field can be passed. This enables two + general locking cases: + + * lock a new buffer: The caller requests a lock at the same time as + requesting the buffer (i.e. ``buf`` is NULL), in an atomic + operation. + + * lock an existing buffer: The caller has already received a buffer + view and now wants to gain a lock on the existing buffer (i.e. + ``buf`` is a valid buffer pointer). Note that the provider is + free to change the ``buf`` pointer during this call, so the + previously used buffer may become invalid. + + If the call succeeds, this means that the consumer now has the + exclusive requested rights on the buffer. The lock can be released + by either calling ``releasebuffer`` on the Py_buffer, or by + explicitly releasing the lock in a subsequent call to ``getbuffer`` + that sets the ``PyBUF_UNLOCK`` flag. + +``PyBUF_UNLOCK`` + + This flag requests to release the lock on an existing buffer, while + keeping the Py_buffer view alive. The ``buf`` field must be + initialised by a previous call to ``getbuffer`` and should have + been locked before (if is not an error if the buffer is not + currently locked). Similar to the LOCK call, the provider may + decide to change the ``buf`` field in this case, so the previous + buffer may become invalid. + + The provider is free to ignore any flags except for the WRITABLE + flag, so the caller cannot request a new buffer layout with an + UNLOCK call. If the WRITABLE flag is set, only an existing + exclusive write lock will be released, but an existing read lock + will be kept. No new locks can be acquired with an UNLOCK call. + + +Memory layout flags +------------------- + +``PyBUF_SIMPLE`` + + This is the default flag state (0). The returned buffer may or may + not have writable memory. The format will be assumed to be + unsigned bytes . This is a "stand-alone" flag constant. It never + needs to be \|'d to the others. The exporter will raise an error if + it cannot provide such a contiguous buffer of bytes. + ``PyBUF_FORMAT`` The returned buffer must have true format information if this flag @@ -256,7 +307,6 @@ All of these flags imply PyBUF_STRIDES and guarantee that the strides buffer info structure will be filled in correctly. - ``PyBUF_INDIRECT`` (implies ``PyBUF_STRIDES``) The returned buffer must have suboffsets information (which can be @@ -307,6 +357,10 @@ buffer info structure correctly according to the provided flags if a contiguous chunk of "unsigned bytes" is all that can be exported. + +The Py_buffer struct +-------------------- + The bufferinfo structure is:: struct bufferinfo { @@ -322,14 +376,15 @@ void *internal; } Py_buffer; -Before calling the bf_getbuffer function, the bufferinfo structure can be -filled with whatever. Upon return from bf_getbuffer, the bufferinfo -structure is filled in with relevant information about the buffer. -This same bufferinfo structure must be passed to bf_releasebuffer (if -available) when the consumer is done with the memory. The caller is -responsible for keeping a reference to obj until releasebuffer is -called (i.e. the call to bf_getbuffer does not alter the reference -count of obj). +Before calling the bf_getbuffer function, the bufferinfo structure can +be filled with whatever, but the ``buf`` field must be NULL when +requesting a new buffer. Upon return from bf_getbuffer, the +bufferinfo structure is filled in with relevant information about the +buffer. This same bufferinfo structure must be passed to +bf_releasebuffer (if available) when the consumer is done with the +memory. The caller is responsible for keeping a reference to obj until +releasebuffer is called (i.e. the call to bf_getbuffer does not alter +the reference count of obj). The members of the bufferinfo structure are: @@ -344,13 +399,13 @@ ``readonly`` an integer variable to hold whether or not the memory is readonly. 1 means the memory is readonly, zero means the memory is writable, - -1 means the memory was read "locked" when this Py_buffer - structure was filled-in therefore should be unlocked when this - Py_buffer structure is "released." A -2 means this Py_buffer - structure has an exclusive-write lock on the memory. This should - be unlocked when the Py_buffer structure is released. The concept - of locking is not supported by all objects that expose the buffer - protocol. + -1 means the memory was read "locked" either when this Py_buffer + structure was filled-in or later on with an explicit LOCK flag, + therefore should be unlocked when this Py_buffer structure is + "released". A -2 means this Py_buffer structure has an + exclusive-write lock on the memory. This should be unlocked when + the Py_buffer structure is released. The concept of locking is + not supported by all objects that expose the buffer protocol. ``format`` a NULL-terminated format-string (following the struct-style syntax @@ -571,7 +626,7 @@ :: PyObject * PyMemoryView_GetContiguous(PyObject *obj, int buffertype, - char fort) + char fortran) Return a memoryview object to a contiguous chunk of memory represented by obj. If a copy must be made (because the memory pointed to by obj @@ -818,10 +873,10 @@ The proposed locking mechanism relies entirely on the exporter object to not invalidate any of the memory pointed to by the buffer structure -until a corresponding releasebuffer is called. If it wants to be able -to change its own shape and/or strides arrays, then it needs to create -memory for these in the bufferinfo structure and copy information -over. +until a corresponding releasebuffer is called or the UNLOCK flag is +passed to a getbuffer call. If it wants to be able to change its own +shape and/or strides arrays, then it needs to create memory for these +in the bufferinfo structure and copy information over. The sharing of strided memory and suboffsets is new and can be seen as a modification of the multiple-segment interface. It is motivated by
_______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com