Pauli Virtanen <p...@iki.fi> added the comment:

> Hmm, there's a misunderstanding. bf_releasebuffer is called exactly
> once for each call to bf_getbuffer.

Wrong: http://bugs.python.org/issue7433

static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
    int res = 0;
    CHECK_RELEASED_INT(self);
    if (self->view.obj != NULL)
        res = PyObject_GetBuffer(self->view.obj, view, flags);
    if (view)
        dup_buffer(view, &self->view);
    return res;
}

After this, PyBuffer_Release will be called twice: once on the data in *view, 
by whoever acquired the buffer from memoryview, and once on self->view, by 
memory_dealloc. Both with the same bit-by-bit content of the Py_buffer 
structure.

Because there are two Py_buffer structures here, setting view.obj to NULL in 
PyBuffer_Release does not guarantee correct calls to bf_releasebuffer.

Note that the view.internal pointer is also clobbered above.

> >  So, `bf_releasebuffer` cannot rely on (i) the data in Py_buffer
> > being what `bf_getbuffer` put there,
> 
> Well, why should it rely on that?

Because that makes implementing the exporter much easier. Also, writing an 
implementation for MemoryViewObject does not require clobbering the structure, 
and I doubt it helps much.

> > So, `bf_releasebuffer` cannot be used to release any resources
> > allocated in `bf_getbuffer`.
>
> AFAICT, it can. That's what the "internal" pointer is for.

Sure, guaranteeing that view->internal pointer is not toyed with would also be 
enough.

But the documentation should spell out very explicitly what the 
bf_releasebuffer call can rely on.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue10181>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to