[pypy-commit] pypy issue2444: massive hack of CPyBuffer.__del__ to call bf_releasebuffer, new idea needed
mattip
pypy.commits at gmail.com
Mon Dec 12 15:01:51 EST 2016
Author: Matti Picus <matti.picus at gmail.com>
Branch: issue2444
Changeset: r89034:9d872f71a438
Date: 2016-12-12 22:01 +0200
http://bitbucket.org/pypy/pypy/changeset/9d872f71a438/
Log: massive hack of CPyBuffer.__del__ to call bf_releasebuffer, new idea
needed
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -12,7 +12,7 @@
getattrfunc, getattrofunc, setattrofunc, lenfunc, ssizeargfunc, inquiry,
ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc,
cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc,
- readbufferproc, getbufferproc, ssizessizeobjargproc)
+ readbufferproc, getbufferproc, releasebufferproc, ssizessizeobjargproc)
from pypy.module.cpyext.pyobject import make_ref, Py_DecRef
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.module.cpyext.memoryobject import fill_Py_buffer
@@ -321,8 +321,10 @@
# Similar to Py_buffer
_immutable_ = True
- def __init__(self, ptr, size, w_obj, format='B', shape=None,
- strides=None, ndim=1, itemsize=1, readonly=True):
+ def __init__(self, space, ptr, size, w_obj, format='B', shape=None,
+ strides=None, ndim=1, itemsize=1, readonly=True,
+ releasebuffer=None):
+ self.space = space
self.ptr = ptr
self.size = size
self.w_obj = w_obj # kept alive
@@ -338,6 +340,20 @@
self.ndim = ndim
self.itemsize = itemsize
self.readonly = readonly
+ self.releasebuffer = releasebuffer
+
+ def __del__(self):
+ if self.releasebuffer:
+ func_target = rffi.cast(releasebufferproc, self.releasebuffer)
+ with lltype.scoped_alloc(Py_buffer) as pybuf:
+ pybuf.c_buf = self.ptr
+ pybuf.c_len = self.size
+ pybuf.c_ndim = rffi.cast(rffi.INT, self.ndim)
+ for i in range(self.ndim):
+ pybuf.c_shape[i] = self.shape[i]
+ pybuf.c_strides[i] = self.strides[i]
+ pybuf.c_format = rffi.str2charp(self.format)
+ generic_cpy_call(self.space, func_target, self.w_obj, pybuf)
def getlength(self):
return self.size
@@ -369,24 +385,35 @@
def wrap_getreadbuffer(space, w_self, w_args, func):
func_target = rffi.cast(readbufferproc, func)
+ py_obj = make_ref(space, w_self)
+ py_type = py_obj.c_ob_type
+ releasebuffer = py_type.c_tp_as_buffer and py_type.c_tp_as_buffer.c_bf_releasebuffer
with lltype.scoped_alloc(rffi.VOIDPP.TO, 1) as ptr:
index = rffi.cast(Py_ssize_t, 0)
size = generic_cpy_call(space, func_target, w_self, index, ptr)
if size < 0:
space.fromcache(State).check_and_raise_exception(always=True)
- return space.newbuffer(CPyBuffer(ptr[0], size, w_self))
+ return space.newbuffer(CPyBuffer(space, ptr[0], size, w_self,
+ releasebuffer=releasebuffer))
def wrap_getwritebuffer(space, w_self, w_args, func):
func_target = rffi.cast(readbufferproc, func)
+ py_obj = make_ref(space, w_self)
+ py_type = py_obj.c_ob_type
+ releasebuffer = py_type.c_tp_as_buffer and py_type.c_tp_as_buffer.c_bf_releasebuffer
with lltype.scoped_alloc(rffi.VOIDPP.TO, 1) as ptr:
index = rffi.cast(Py_ssize_t, 0)
size = generic_cpy_call(space, func_target, w_self, index, ptr)
if size < 0:
space.fromcache(State).check_and_raise_exception(always=True)
- return space.newbuffer(CPyBuffer(ptr[0], size, w_self, readonly=False))
+ return space.newbuffer(CPyBuffer(space, ptr[0], size, w_self, readonly=False,
+ releasebuffer=releasebuffer))
def wrap_getbuffer(space, w_self, w_args, func):
func_target = rffi.cast(getbufferproc, func)
+ py_obj = make_ref(space, w_self)
+ py_type = py_obj.c_ob_type
+ releasebuffer = py_type.c_tp_as_buffer and py_type.c_tp_as_buffer.c_bf_releasebuffer
with lltype.scoped_alloc(Py_buffer) as pybuf:
_flags = 0
if space.len_w(w_args) > 0:
@@ -407,10 +434,11 @@
format = rffi.charp2str(pybuf.c_format)
else:
format = 'B'
- return space.newbuffer(CPyBuffer(ptr, size, w_self, format=format,
+ return space.newbuffer(CPyBuffer(space, ptr, size, w_self, format=format,
ndim=ndim, shape=shape, strides=strides,
itemsize=pybuf.c_itemsize,
- readonly=widen(pybuf.c_readonly)))
+ readonly=widen(pybuf.c_readonly),
+ releasebuffer = releasebuffer))
def get_richcmp_func(OP_CONST):
def inner(space, w_self, w_args, func):
diff --git a/pypy/module/cpyext/typeobjectdefs.py b/pypy/module/cpyext/typeobjectdefs.py
--- a/pypy/module/cpyext/typeobjectdefs.py
+++ b/pypy/module/cpyext/typeobjectdefs.py
@@ -60,7 +60,7 @@
segcountproc = P(FT([PyO, Py_ssize_tP], Py_ssize_t))
charbufferproc = P(FT([PyO, Py_ssize_t, rffi.CCHARPP], Py_ssize_t))
getbufferproc = P(FT([PyO, Py_bufferP, rffi.INT_real], rffi.INT_real))
-releasebufferproc = rffi.VOIDP
+releasebufferproc = P(FT([PyO, Py_bufferP], Void))
PyGetSetDef = cpython_struct("PyGetSetDef", (
More information about the pypy-commit
mailing list