[Python-checkins] python/nondist/peps pep-0298.txt,1.4,1.5

theller@users.sourceforge.net theller@users.sourceforge.net
Thu, 01 Aug 2002 11:24:08 -0700


Update of /cvsroot/python/python/nondist/peps
In directory usw-pr-cvs1:/tmp/cvs-serv24547

Modified Files:
	pep-0298.txt 
Log Message:
Renamed everything from 'fixed buffer' to 'locked buffer'.

Recommandations on how to implement the interface.


Index: pep-0298.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0298.txt,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** pep-0298.txt	31 Jul 2002 18:48:36 -0000	1.4
--- pep-0298.txt	1 Aug 2002 18:24:06 -0000	1.5
***************
*** 1,4 ****
  PEP: 298
! Title: The Fixed Buffer Interface
  Version: $Revision$
  Last-Modified: $Date$
--- 1,4 ----
  PEP: 298
! Title: The Locked Buffer Interface
  Version: $Revision$
  Last-Modified: $Date$
***************
*** 8,12 ****
  Created: 26-Jul-2002
  Python-Version: 2.3
! Post-History: 30-Jul-2002
  
  
--- 8,12 ----
  Created: 26-Jul-2002
  Python-Version: 2.3
! Post-History: 30-Jul-2002, 1-Aug-2002
  
  
***************
*** 14,20 ****
  
      This PEP proposes an extension to the buffer interface called the
!     'fixed buffer interface'.
  
!     The fixed buffer interface fixes the flaws of the 'old' buffer
      interface [1] as defined in Python versions up to and including
      2.2, and has the following semantics:
--- 14,20 ----
  
      This PEP proposes an extension to the buffer interface called the
!     'locked buffer interface'.
  
!     The locked buffer interface avoids the flaws of the 'old' buffer
      interface [1] as defined in Python versions up to and including
      2.2, and has the following semantics:
***************
*** 34,38 ****
  Specification
  
!     The fixed buffer interface exposes new functions which return the
      size and the pointer to the internal memory block of any python
      object which chooses to implement this interface.
--- 34,38 ----
  Specification
  
!     The locked buffer interface exposes new functions which return the
      size and the pointer to the internal memory block of any python
      object which chooses to implement this interface.
***************
*** 43,55 ****
  
      The object must be unlocked again by releasing the buffer if it's
!     no longer used by calling another function in the fixed buffer
      interface.  If the object never resizes or reallocates the buffer
!     during it's lifetime, this function may be NULL. Failure to call
      this function (if it is != NULL) is a programming error and may
      have unexpected results.
  
!     The fixed buffer interface omits the memory segment model which is
!     present in the old buffer interface - only a single memory block
!     can be exposed.
  
  
--- 43,55 ----
  
      The object must be unlocked again by releasing the buffer if it's
!     no longer used by calling another function in the locked buffer
      interface.  If the object never resizes or reallocates the buffer
!     during it's lifetime, this function may be NULL.  Failure to call
      this function (if it is != NULL) is a programming error and may
      have unexpected results.
  
!     The locked buffer interface omits the memory segment model which
!     is present in the old buffer interface - only a single memory
!     block can be exposed.
  
  
***************
*** 58,64 ****
      Define a new flag in Include/object.h:
  
!         /* PyBufferProcs contains bf_acquirefixedreadbuffer,
!            bf_acquirefixedwritebuffer, and bf_releasefixedbuffer */
!         #define Py_TPFLAGS_HAVE_FIXEDBUFFER (1L<<15)
  
  
--- 58,64 ----
      Define a new flag in Include/object.h:
  
!         /* PyBufferProcs contains bf_acquirelockedreadbuffer,
!            bf_acquirelockedwritebuffer, and bf_releaselockedbuffer */
!         #define Py_TPFLAGS_HAVE_LOCKEDBUFFER (1L<<15)
  
  
***************
*** 67,71 ****
          #define Py_TPFLAGS_DEFAULT  ( \
                               ....
!                              Py_TPFLAGS_HAVE_FIXEDBUFFER | \
                               ....
                              0)
--- 67,71 ----
          #define Py_TPFLAGS_DEFAULT  ( \
                               ....
!                              Py_TPFLAGS_HAVE_LOCKEDBUFFER | \
                               ....
                              0)
***************
*** 75,103 ****
      Include/object.h:
  
!         typedef size_t (*acquirefixedreadbufferproc)(PyObject *,
!                                                      const void **);
!         typedef size_t (*acquirefixedwritebufferproc)(PyObject *,
!                                                       void **);
!         typedef void (*releasefixedbufferproc)(PyObject *);
  
          typedef struct {
!                 getreadbufferproc bf_getreadbuffer;
!                 getwritebufferproc bf_getwritebuffer;
!                 getsegcountproc bf_getsegcount;
!                 getcharbufferproc bf_getcharbuffer;
!                 /* fixed buffer interface functions */
!                 acquirefixedreadbufferproc bf_acquirefixedreadbuffer;
!                 acquirefixedwritebufferproc bf_acquirefixedwritebuffer;
!                 releasefixedbufferproc bf_releasefixedbuffer;
          } PyBufferProcs;
  
  
!     The new fields are present if the Py_TPFLAGS_HAVE_FIXEDBUFFER
      flag is set in the object's type.
  
!     The Py_TPFLAGS_HAVE_FIXEDBUFFER flag implies the
      Py_TPFLAGS_HAVE_GETCHARBUFFER flag.
  
!     The acquirefixedreadbufferproc and acquirefixedwritebufferproc
      functions return the size in bytes of the memory block on success,
      and fill in the passed void * pointer on success.  If these
--- 75,103 ----
      Include/object.h:
  
!         typedef size_t (*acquirelockedreadbufferproc)(PyObject *,
!                                                       const void **);
!         typedef size_t (*acquirelockedwritebufferproc)(PyObject *,
!                                                        void **);
!         typedef void (*releaselockedbufferproc)(PyObject *);
  
          typedef struct {
!             getreadbufferproc bf_getreadbuffer;
!             getwritebufferproc bf_getwritebuffer;
!             getsegcountproc bf_getsegcount;
!             getcharbufferproc bf_getcharbuffer;
!             /* locked buffer interface functions */
!             acquirelockedreadbufferproc bf_acquirelockedreadbuffer;
!             acquirelockedwritebufferproc bf_acquirelockedwritebuffer;
!             releaselockedbufferproc bf_releaselockedbuffer;
          } PyBufferProcs;
  
  
!     The new fields are present if the Py_TPFLAGS_HAVE_LOCKEDBUFFER
      flag is set in the object's type.
  
!     The Py_TPFLAGS_HAVE_LOCKEDBUFFER flag implies the
      Py_TPFLAGS_HAVE_GETCHARBUFFER flag.
  
!     The acquirelockedreadbufferproc and acquirelockedwritebufferproc
      functions return the size in bytes of the memory block on success,
      and fill in the passed void * pointer on success.  If these
***************
*** 108,131 ****
  
      If calls to these functions succeed, eventually the buffer must be
!     released by a call to the releasefixedbufferproc, supplying the
!     original object as argument.  The releasefixedbufferproc cannot
!     fail.
  
!     Usually these functions aren't called directly, they are called
!     through convenience functions declared in Include/abstract.h:
  
!         int PyObject_AquireFixedReadBuffer(PyObject *obj,
!                                            const void **buffer,
!                                            size_t *buffer_len);
  
!         int PyObject_AcquireFixedWriteBuffer(PyObject *obj,
!                                              void **buffer,
!                                              size_t *buffer_len);
  
!         void PyObject_ReleaseFixedBuffer(PyObject *obj);
  
      The former two functions return 0 on success, set buffer to the
      memory location and buffer_len to the length of the memory block
!     in bytes. On failure, or if the fixed buffer interface is not
      implemented by obj, they return -1 and set an exception.
  
--- 108,141 ----
  
      If calls to these functions succeed, eventually the buffer must be
!     released by a call to the releaselockedbufferproc, supplying the
!     original object as argument.  The releaselockedbufferproc cannot
!     fail.  For objects that actually maintain an internal lock count
!     it would be a fatal error if the releaselockedbufferproc function
!     would be called too often, leading to a negative lock count.
  
!     Similar to the 'old' buffer interface, any of these functions may
!     be set to NULL, but it is strongly recommended to implement the
!     releaselockedbufferproc function (even if it does nothing) if any
!     of the acquireread/writelockedbufferproc functions are
!     implemented, to discourage extension writers from checking for a
!     NULL value and not calling it.
  
!     These functions aren't supposed to be called directly, they are
!     called through convenience functions declared in
!     Include/abstract.h:
  
!         int PyObject_AquireLockedReadBuffer(PyObject *obj,
!                                             const void **buffer,
!                                             size_t *buffer_len);
  
!         int PyObject_AcquireLockedWriteBuffer(PyObject *obj,
!                                               void **buffer,
!                                               size_t *buffer_len);
! 
!         void PyObject_ReleaseLockedBuffer(PyObject *obj);
  
      The former two functions return 0 on success, set buffer to the
      memory location and buffer_len to the length of the memory block
!     in bytes. On failure, or if the locked buffer interface is not
      implemented by obj, they return -1 and set an exception.
  
***************
*** 147,157 ****
  Additional Notes/Comments
  
!     Python strings, Unicode strings, mmap objects, and array objects
!     would expose the fixed buffer interface.
  
  
  Community Feedback
  
!     Greg Ewing doubts the fixed buffer interface is needed at all, he
      thinks the normal buffer interface could be used if the pointer is
      (re)fetched each time it's used.  This seems to be dangerous,
--- 157,194 ----
  Additional Notes/Comments
  
!     Python strings, unicode strings, mmap objects, and array objects
!     would expose the locked buffer interface.
! 
!     mmap and array objects would actually enter a locked state while
!     the buffer is active, this is not needed for strings and unicode
!     objects.  Resizing locked array objects is not allowed and will
!     raise an exception. Whether closing a locked mmap object is an
!     error or will only be deferred until the lock count reaches zero
!     is an implementation detail.
! 
!     Guido recommends:
! 
!         But I'm still very concerned that if most built-in types
!         (e.g. strings, bytes) don't implement the release
!         functionality, it's too easy for an extension to seem to work
!         while forgetting to release the buffer.
! 
!         I recommend that at least some built-in types implement the
!         acquire/release functionality with a counter, and assert that
!         the counter is zero when the object is deleted -- if the
!         assert fails, someone DECREF'ed their reference to the object
!         without releasing it.  (The rule should be that you must own a
!         reference to the object while you've aquired the object.)
! 
!         For strings that might be impractical because the string
!         object would have to grow 4 bytes to hold the counter; but the
!         new bytes object (PEP 296) could easily implement the counter,
!         and the array object too -- that way there will be plenty of
!         opportunity to test proper use of the protocol.
  
  
  Community Feedback
  
!     Greg Ewing doubts the locked buffer interface is needed at all, he
      thinks the normal buffer interface could be used if the pointer is
      (re)fetched each time it's used.  This seems to be dangerous,
***************
*** 167,172 ****
  
  Credits
- 
-     Scott Gilbert came up with the name 'fixed buffer interface'.
  
  
--- 204,207 ----