Author: Matti Picus <matti.pi...@gmail.com> Branch: issue2444 Changeset: r89121:f66ee40b4bc5 Date: 2016-12-17 20:14 +0200 http://bitbucket.org/pypy/pypy/changeset/f66ee40b4bc5/
Log: use FinalizerQueue (with minor hack for tests) 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 @@ -4,6 +4,7 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib.rarithmetic import widen +from rpython.rlib import rgc # Force registration of gc.collect from pypy.module.cpyext.api import ( cpython_api, generic_cpy_call, PyObject, Py_ssize_t, Py_TPFLAGS_CHECKTYPES, mangle_name, pypy_decl, Py_buffer, Py_bufferP) @@ -343,7 +344,6 @@ self.releasebufferproc = releasebuffer def releasebuffer(self): - print '--------------' if self.releasebufferproc: func_target = rffi.cast(releasebufferproc, self.releasebufferproc) with lltype.scoped_alloc(Py_buffer) as pybuf: @@ -385,6 +385,17 @@ # absolutely no safety checks, what could go wrong? self.ptr[index] = char +class FQ(rgc.FinalizerQueue): + Class = CPyBuffer + def finalizer_trigger(self): + while 1: + buf = self.next_dead() + if not buf: + break + buf.releasebuffer() + +fq = FQ() + def wrap_getreadbuffer(space, w_self, w_args, func): func_target = rffi.cast(readbufferproc, func) py_obj = make_ref(space, w_self) @@ -395,8 +406,10 @@ 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(space, ptr[0], size, w_self, - releasebuffer=releasebuffer)) + buf = CPyBuffer(space, ptr[0], size, w_self, + releasebuffer=releasebuffer) + fq.register_finalizer(buf) + return space.newbuffer(buf) def wrap_getwritebuffer(space, w_self, w_args, func): func_target = rffi.cast(readbufferproc, func) @@ -408,8 +421,10 @@ 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(space, ptr[0], size, w_self, readonly=False, - releasebuffer=releasebuffer)) + buf = CPyBuffer(space, ptr[0], size, w_self, readonly=False, + releasebuffer=releasebuffer) + fq.register_finalizer(buf) + return space.newbuffer(buf) def wrap_getbuffer(space, w_self, w_args, func): func_target = rffi.cast(getbufferproc, func) @@ -436,11 +451,13 @@ format = rffi.charp2str(pybuf.c_format) else: format = 'B' - return space.newbuffer(CPyBuffer(space, ptr, size, w_self, format=format, + buf = CPyBuffer(space, ptr, size, w_self, format=format, ndim=ndim, shape=shape, strides=strides, itemsize=pybuf.c_itemsize, readonly=widen(pybuf.c_readonly), - releasebuffer = releasebuffer)) + releasebuffer = releasebuffer) + fq.register_finalizer(buf) + return space.newbuffer(buf) def get_richcmp_func(OP_CONST): def inner(space, w_self, w_args, func): diff --git a/pypy/module/cpyext/test/test_bufferobject.py b/pypy/module/cpyext/test/test_bufferobject.py --- a/pypy/module/cpyext/test/test_bufferobject.py +++ b/pypy/module/cpyext/test/test_bufferobject.py @@ -114,9 +114,8 @@ """, ) import gc assert module.get_cnt() == 0 - print '++++++++++++++++++' a = memoryview(module.create_test()) - print 'xxxxxxxxxxxxxxxxxxxxxxx' assert module.get_cnt() == 1 del a + gc.collect(); gc.collect(); gc.collect() assert module.get_cnt() == 0 diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -323,7 +323,6 @@ def newbuffer(self, obj): ret = W_Buffer(obj) - ret.register_finalizer(self) return ret def newbytes(self, s): diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -450,6 +450,7 @@ "the object must have a __dict__" % (obj,)) assert (not hasattr(obj, '__slots__') or type(obj).__slots__ == () or + type(obj).__slots__ == ['readonly'] or type(obj).__slots__ == ('__weakref__',)), ( "%r: to run register_finalizer() untranslated, " "the object must not have __slots__" % (obj,)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit