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

Reply via email to