[pypy-commit] pypy default: Add a previously-failing test for the GC not handling multiple

arigo pypy.commits at gmail.com
Tue Mar 21 07:34:25 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r90777:761bc7504874
Date: 2017-03-21 12:33 +0100
http://bitbucket.org/pypy/pypy/changeset/761bc7504874/

Log:	Add a previously-failing test for the GC not handling multiple
	ThreadLocalReferences, fixed by f3f2566b1a08

diff --git a/rpython/rlib/test/test_rthread.py b/rpython/rlib/test/test_rthread.py
--- a/rpython/rlib/test/test_rthread.py
+++ b/rpython/rlib/test/test_rthread.py
@@ -262,15 +262,23 @@
             py.test.skip("no __thread support here")
 
         class FooBar(object):
-            pass
+            def __init__(self, a, b):
+                self.lst = [a, b]
         t = ThreadLocalReference(FooBar)
+        t2 = ThreadLocalReference(FooBar)
 
         def tset():
-            x1 = FooBar()
+            x1 = FooBar(40, 2)
             t.set(x1)
             return weakref.ref(x1)
         tset._dont_inline_ = True
 
+        def t2set():
+            x1 = FooBar(50, 3)
+            t2.set(x1)
+            return weakref.ref(x1)
+        t2set._dont_inline_ = True
+
         class WrFromThread:
             pass
         wr_from_thread = WrFromThread()
@@ -279,22 +287,30 @@
             config = objectmodel.fetch_translated_config()
             assert t.automatic_keepalive(config) is True
             wr = tset()
-            import gc; gc.collect()   # 'x1' should not be collected
-            x2 = t.get()
+            wr2 = t2set()
+            import gc; gc.collect()   # the two 'x1' should not be collected
+            x1 = t.get()
+            assert x1 is not None
+            assert wr() is not None
+            assert wr() is x1
+            assert x1.lst == [40, 2]
+            x2 = t2.get()
             assert x2 is not None
-            assert wr() is not None
-            assert wr() is x2
-            return wr
+            assert wr2() is not None
+            assert wr2() is x2
+            assert x2.lst == [50, 3]
+            return wr, wr2
 
         def thread_entry_point():
-            wr = f()
+            wr, wr2 = f()
             wr_from_thread.wr = wr
+            wr_from_thread.wr2 = wr2
             wr_from_thread.seen = True
 
         def main():
             wr_from_thread.seen = False
             start_new_thread(thread_entry_point, ())
-            wr1 = f()
+            wr1, wr2 = f()
             count = 0
             while True:
                 time.sleep(0.5)
@@ -302,10 +318,15 @@
                     break
                 count += 1
             assert wr_from_thread.seen is True
-            wr2 = wr_from_thread.wr
-            import gc; gc.collect()      # wr2() should be collected here
+            wr_other_1 = wr_from_thread.wr
+            wr_other_2 = wr_from_thread.wr2
+            import gc; gc.collect()      # wr_other_*() should be collected here
             assert wr1() is not None     # this thread, still running
-            assert wr2() is None         # other thread, not running any more
+            assert wr2() is not None     # this thread, still running
+            assert wr_other_1() is None  # other thread, not running any more
+            assert wr_other_2() is None  # other thread, not running any more
+            assert wr1().lst == [40, 2]
+            assert wr2().lst == [50, 3]
             return 42
 
         extra_options = {'no__thread': no__thread, 'shared': True}


More information about the pypy-commit mailing list