Commit 470c22c1 authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'bugs'

parents c006cc2b b69124e0
...@@ -1129,6 +1129,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1129,6 +1129,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
or memoryview_slices or memoryview_slices
or weakref_slot in scope.var_entries): or weakref_slot in scope.var_entries):
self.generate_self_cast(scope, code) self.generate_self_cast(scope, code)
# We must mark ths object as (gc) untracked while tearing it down, lest
# the garbage collection is invoked while running this destructor.
if scope.needs_gc():
code.putln("PyObject_GC_UnTrack(o);");
# call the user's __dealloc__ # call the user's __dealloc__
self.generate_usr_dealloc_call(scope, code) self.generate_usr_dealloc_call(scope, code)
...@@ -1153,6 +1158,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1153,6 +1158,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_xdecref_memoryviewslice("p->%s" % entry.cname, code.put_xdecref_memoryviewslice("p->%s" % entry.cname,
have_gil=True) have_gil=True)
# The base class deallocator probably expects this to be tracked, so
# undo the untracking above.
if scope.needs_gc():
code.putln("PyObject_GC_Track(o);");
if base_type: if base_type:
tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
if tp_dealloc is not None: if tp_dealloc is not None:
......
include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt CHANGES.rst
include COPYING.txt LICENSE.txt Makefile include COPYING.txt LICENSE.txt Makefile
include .gitrev include .gitrev
include setup.py include setup.py
......
"""
>>> x = SimpleGarbage()
SimpleGarbage(1) __cinit__
>>> del x
SimpleGarbage(1) __dealloc__
Collector.__dealloc__
collect 0
"""
import gc, sys, weakref
cdef int counter = 0
cdef int next_counter():
global counter
counter += 1
return counter
cdef class Collector:
# Indirectly trigger garbage collection in SimpleGarbage deallocation.
# The __dealloc__ method of SimpleGarbage won't trigger the bug as the
# refcount is artifitially inflated for the durration of that function.
def __dealloc__(self):
print "Collector.__dealloc__"
print "collect", gc.collect()
cdef class SimpleGarbage:
cdef Collector c # to particpate in garbage collection
cdef int index
cdef bint deallocated
def __cinit__(self):
self.index = next_counter()
self.c = Collector()
print self, "__cinit__"
def __dealloc__(self):
print self, "__dealloc__"
if self.deallocated:
print "Double dealloc!"
self.deallocated = True
gc.collect()
def __str__(self):
return "SimpleGarbage(%s)" % self.index
def __repr__(self):
return "SimpleGarbage(%s)" % self.index
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment