Author: Antonio Cuni <[email protected]>
Branch: gc-hooks
Changeset: r94248:df2490d5d814
Date: 2018-04-05 13:41 +0200
http://bitbucket.org/pypy/pypy/changeset/df2490d5d814/
Log: argh, this was a bad bug: make sure to clear action._next after
perform(), else the next time we put it in the queue, the ._next
link will point to a spurious action
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -430,6 +430,7 @@
@rgc.no_collect
def _fired_actions_append(self, action):
+ assert action._next is None
if self._fired_actions_first is None:
self._fired_actions_first = action
self._fired_actions_last = action
@@ -494,7 +495,7 @@
while action is not None:
action._fired = False
action.perform(ec, frame)
- action = action._next
+ action._next, action = None, action._next
self.action_dispatcher = action_dispatcher
diff --git a/pypy/interpreter/test/test_executioncontext.py
b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -37,6 +37,37 @@
pass
assert i == 9
+ def test_action_queue(self):
+ events = []
+
+ class Action1(executioncontext.AsyncAction):
+ def perform(self, ec, frame):
+ events.append('one')
+
+ class Action2(executioncontext.AsyncAction):
+ def perform(self, ec, frame):
+ events.append('two')
+
+ space = self.space
+ a1 = Action1(space)
+ a2 = Action2(space)
+ a1.fire()
+ a2.fire()
+ space.appexec([], """():
+ n = 5
+ return n + 2
+ """)
+ assert events == ['one', 'two']
+ #
+ events[:] = []
+ a1.fire()
+ space.appexec([], """():
+ n = 5
+ return n + 2
+ """)
+ assert events == ['one']
+
+
def test_periodic_action(self):
from pypy.interpreter.executioncontext import ActionFlag
diff --git a/pypy/module/gc/test/test_hook.py b/pypy/module/gc/test/test_hook.py
--- a/pypy/module/gc/test/test_hook.py
+++ b/pypy/module/gc/test/test_hook.py
@@ -21,9 +21,16 @@
def fire_gc_collect(space, a, b, c, d, e, f):
gchooks.fire_gc_collect(a, b, c, d, e, f)
+ @unwrap_spec(ObjSpace)
+ def fire_many(space):
+ gchooks.fire_gc_minor(0, 0)
+ gchooks.fire_gc_collect_step(0, 0)
+ gchooks.fire_gc_collect(1, 2, 3, 4, 5, 6)
+
cls.w_fire_gc_minor = space.wrap(interp2app(fire_gc_minor))
cls.w_fire_gc_collect_step =
space.wrap(interp2app(fire_gc_collect_step))
cls.w_fire_gc_collect = space.wrap(interp2app(fire_gc_collect))
+ cls.w_fire_many = space.wrap(interp2app(fire_many))
def test_on_gc_minor(self):
import gc
@@ -98,3 +105,19 @@
assert S.STATE_SWEEPING == 2
assert S.STATE_FINALIZING == 3
assert S.GC_STATES == ('SCANNING', 'MARKING', 'SWEEPING', 'FINALIZING')
+
+ def test_clear_queue(self):
+ import gc
+ lst = []
+ def on_gc_minor(stats): lst.append('minor')
+ def on_gc_collect_step(stats): lst.append('step')
+ def on_gc_collect(stats): lst.append('collect')
+ gc.set_hooks(on_gc_minor=on_gc_minor,
+ on_gc_collect_step=on_gc_collect_step,
+ on_gc_collect=on_gc_collect)
+ #
+ self.fire_many()
+ assert lst == ['minor', 'step', 'collect']
+ lst[:] = []
+ self.fire_gc_minor(0, 0)
+ assert lst == ['minor']
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit