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
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com