Commits

Remi Meier  committed fcc562f

stm: at_commit clarification for what happens if registering more callbacks during a callback

  • Participants
  • Parent commits 535f5ae
  • Branches stm-logging

Comments (0)

Files changed (2)

File pypy/module/thread/stm.py

     from pypy.rlib.objectmodel import we_are_translated
 
     ec = space.getexecutioncontext()
-    if ec._at_commit_cbs is not None:
-        if ec._at_commit_cbs:
+    if ec._at_commit_cbs is not None and len(ec._at_commit_cbs):
+        if we_are_translated():
+            if rstm.is_atomic() == 0:
+                # allowed to become inevitable
+                rstm.become_inevitable()
+            rstm.increment_atomic()
+        try:
+            # Attention: callbacks added during another
+            # callback will be executed in the same transaction
+            # -> infinite loop if adding itself
+            i = 0
+            while i < len(ec._at_commit_cbs):
+                w_cb, args = ec._at_commit_cbs[i]
+                i += 1
+                try:
+                    space.call_args(w_cb, args)
+                except OperationError, e:
+                    # XXX: what to do?
+                    # for now call the other callbacks so that unrelated
+                    # objects are unaffected
+                    pass
+        finally:
+            ec._at_commit_cbs = []
             if we_are_translated():
-                rstm.become_inevitable()
-                rstm.increment_atomic()
-            try:
-                for w_cb, args in ec._at_commit_cbs:
-                    try:
-                        space.call_args(w_cb, args)
-                    except OperationError, e:
-                        # XXX: what to do?
-                        # for now call the other callbacks so that unrelated
-                        # objects are unaffected
-                        pass
-            finally:
-                ec._at_commit_cbs = []
-                if we_are_translated():
-                    rstm.decrement_atomic()
+                rstm.decrement_atomic()
 
 def should_commit(space):
     from pypy.rlib import rstm

File pypy/module/thread/test/test_at_commit.py

         thread.at_commit(good, (l,))
         thread.run_commit()
         assert l[0] == 1 and len(l) == 1
+
+    def test_recursive(self):
+        import thread
+
+        def second(l):
+            l.append(1)
+        def first(l):
+            thread.at_commit(second, (l,))
+            
+        l = []
+        thread.at_commit(first, (l,))
+        thread.run_commit()
+        assert l[0] == 1 and len(l) == 1