[Python-3000] PEP Draft: Enhancing the buffer protcol
Travis E. Oliphant
oliphant.travis at ieee.org
Wed Feb 28 05:05:23 CET 2007
Daniel Stutzbach wrote:
> I know I'm joining this discussion late in the game, so I apologize if
> my look through the list archives was not sufficiently exhaustive and
> this has been proposed and shot down before...
No, I don't think you are late. But this discussion has been going on
off and on for at least 10 years :-) We don't all remember all the
issues, though.
>
> What if the locking mechanism were put into the array's memory instead
> of the container's memory?
Basically, my first proposal was to have a single view object and you
would get at the memory through it. But, having a light-weight API that
returns a pointer to memory like the current one does is desirable.
> If the array-memory is a PyObject, then
> the existing reference counting mechanism can be used, instead of
> inventing a new one. We can introduce a new type, PyArray, that is
> pretty much opaque (bare minimum of methods). A PyArray is just a
> PyObject_HEAD (one type pointer plus the reference counter) followed
> by the data that would normally be there.
>
The original object still needs to distinguish between normal references
and "view-based references." Thus, even with your proposal it seems you
will need another counter on the objects that wish to track
buffer-interface views.
> When an array-like container allocates memory, it allocates a PyArray
> to store the actual data in. When a caller request a view, the
> container increments the PyArray's reference counter and returns a
> pointer to the PyArray. The caller is responsible for decrementing
> the reference counter when it is done with the view, so
> bf_releasebuffer becomes unnecessary.
Maybe I'm not understanding you correctly. Perhaps what you are saying
is that we should have all memory allocation go through a light-weight
memory-object. Then, you would get this object + an offset when you
wanted a pointer into memory.
This way, the memory would never be deallocated until nothing was
referencing it. I think this approach would work. However, you could
still have the case, where an object reallocated memory while another
object which thought it had a view of that object ended up with a
"out-dated" view. You just wouldn't segfault in that case.
You could check the reference count on the memory object, before
reallocating, I suppose. But I've heard that the reference counts on
Python objects can be larger than 1 in some cases (even though there
isn't really anything "viewing" the memory).
>
> The container cannot reallocate the memory unless the reference
> counter on the PyArray is exactly 1.
I'm not sure we can guarantee this would work. It seems like for
various reasons depending on the state of the interpreter, reference
counts increase.
>
> Basically, I'm wondering if it makes sense to move the new reference
> counter into the buffered memory rather than putting it in the
> container, so that there is only one reference counter implementation.
>
This is an idea I've thought of too, but we would be enforcing a
"use-python for all shared memory allocations" restriction.
> Different question: what is a container supposed to do if a view is
> locking its memory and it needs to reallocate to complete some
> operation? I assume it would raise an exception, but it would be nice
> to spell this out in the PEP.
It would raise an exception.
-Travis
More information about the Python-3000
mailing list