[pypy-svn] r22501 - pypy/dist/pypy/lib/logic

auc at codespeak.net auc at codespeak.net
Mon Jan 23 11:30:56 CET 2006


Author: auc
Date: Mon Jan 23 11:30:54 2006
New Revision: 22501

Modified:
   pypy/dist/pypy/lib/logic/test_unification.py
   pypy/dist/pypy/lib/logic/unification.py
Log:
check concurrent binding (auc, ale)


Modified: pypy/dist/pypy/lib/logic/test_unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/test_unification.py	(original)
+++ pypy/dist/pypy/lib/logic/test_unification.py	Mon Jan 23 11:30:54 2006
@@ -3,14 +3,24 @@
 from py.test import raises, skip
 from threading import Thread
 
+class FunThread(Thread):
+
+    def __init__(self, fun, *args):
+        Thread.__init__(self)
+        self.fun = fun
+        self.args = args
+
+    def run(self):
+        self.fun(self, *self.args)
+
 class TestUnification:
     
     def setup_method(self, meth):
         u._store = u.Store()
 
-##     def test_already_in_store(self):
-##         x = u.var('x')
-##         raises(u.AlreadyInStore, u.var, 'x')
+    def test_already_in_store(self):
+        x = u.var('x')
+        raises(v.AlreadyExists, u.var, 'x')
 
     def test_already_bound(self):
         x = u.var('x')
@@ -105,25 +115,50 @@
         
         
     def test_threads_creating_vars(self):
-        def create_var(*args):
+        def create_var(thread, *args):
             x = u.var('x')
 
-        def create_var2(*args):
+        def create_var2(thread, *args):
             raises(v.AlreadyExists, u.var, 'x')
 
         t1, t2 = (FunThread(create_var),
                   FunThread(create_var2))
         t1.start()
         t2.start()
+
+
+    def test_threads_binding_vars(self):
         
+        def do_stuff(thread, var, val):
+            thread.raised = False
+            try:
+                u.bind(var, val)
+            except u.AlreadyBound:
+                thread.raised = True
+            
+        x = u.var('x')
+        vars_ = []
+        for nvar in range(1000):
+            v = u.var('x-'+str(nvar))
+            u.bind(x, v)
+            vars_.append(v)
+
+        for var in u._store.vars:
+            assert var.val == x.val
+
+        t1, t2 = (FunThread(do_stuff, x, 42),
+                  FunThread(do_stuff, x, 43))
+        t1.start()
+        t2.start()
+        t1.join()
+        t2.join()
+        #check that every var is really bound to 42 or 43
+        for var in u._store.vars:
+            assert var.val == x.val
+        assert (t2.raised and not t1.raised) or \
+               (t1.raised and not t2.raised)
+    
 
-class FunThread(Thread):
 
-    def __init__(self, fun, *args):
-        Thread.__init__(self)
-        self.fun = fun
-        self.args = args
 
-    def run(self):
-        self.fun(self.args)
             

Modified: pypy/dist/pypy/lib/logic/unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/unification.py	(original)
+++ pypy/dist/pypy/lib/logic/unification.py	Mon Jan 23 11:30:54 2006
@@ -118,6 +118,8 @@
 # * add entailment checks
 # * add constraints support
 
+import threading
+
 from variable import EqSet, Var, VariableException, NotAVariable
 
 #----------- Store Exceptions ----------------------------
@@ -156,6 +158,7 @@
         self.vars = set()
         self.names = set()
         self.in_transaction = False
+        self.lock = threading.Lock()
 
     def add_unbound(self, var):
         # register globally
@@ -174,6 +177,7 @@
            2. (unbound)Variable/(bound)Variable or
            3. (unbound)Variable/Value binding
         """
+        self.lock.acquire()
         assert(isinstance(var, Var) and (var in self.vars))
         if var == val:
             return
@@ -190,16 +194,17 @@
             if var._is_bound():
                 raise AlreadyBound(var.name)
             self._bind(var.val, val)
+        self.lock.release()
 
 
     def _bind(self, eqs, val):
-        print "variable - value binding : %s %s" % (eqs, val)
+        # print "variable - value binding : %s %s" % (eqs, val)
         # bind all vars in the eqset to obj
         for var in eqs:
             var.val = val
 
     def _merge(self, eqs1, eqs2):
-        print "unbound variables binding : %s %s" % (eqs1, eqs2)
+        # print "unbound variables binding : %s %s" % (eqs1, eqs2)
         if eqs1 == eqs2: return
         # merge two equisets into one
         eqs1 |= eqs2



More information about the Pypy-commit mailing list