[pypy-commit] pypy stm-thread: Temporary workaround: in a "with atomic" it is not allowed to

arigo noreply at buildbot.pypy.org
Tue May 8 16:29:48 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread
Changeset: r54958:d06ef1171b9c
Date: 2012-05-08 16:29 +0200
http://bitbucket.org/pypy/pypy/changeset/d06ef1171b9c/

Log:	Temporary workaround: in a "with atomic" it is not allowed to
	acquire any lock. That's too strong a restriction, because it
	prevents us from doing anything with files. Well, this is work-in-
	progress and it's still better than random deadlocks.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -682,7 +682,11 @@
     def __allocate_lock(self):
         from pypy.module.thread.ll_thread import allocate_lock, error
         try:
-            return allocate_lock()
+            if self.config.translation.stm:
+                from pypy.module.thread import stm
+                return stm.allocate_stm_lock(self)
+            else:
+                return allocate_lock()
         except error:
             raise OperationError(self.w_RuntimeError,
                                  self.wrap("out of resources"))
diff --git a/pypy/module/thread/atomic.py b/pypy/module/thread/atomic.py
--- a/pypy/module/thread/atomic.py
+++ b/pypy/module/thread/atomic.py
@@ -1,21 +1,18 @@
 from pypy.interpreter.error import OperationError
 from pypy.rlib.rstm import increment_atomic, decrement_atomic, is_atomic
-
-def get_w_error(space):
-    from pypy.module.thread import error
-    return space.fromcache(error.Cache).w_error
+from pypy.module.thread.error import wrap_thread_error
 
 def atomic_enter(space):
     if not space.config.translation.stm:
-        raise OperationError(get_w_error(space),
-            space.wrap("atomic.__enter__(): STM not available"))
+        raise wrap_thread_error(space,
+            "atomic.__enter__(): STM not available")
     increment_atomic()
 
 def atomic_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None):
     if not space.config.translation.stm:
-        raise OperationError(get_w_error(space),
-            space.wrap("atomic.__exit__(): STM not available"))
+        raise wrap_thread_error(space,
+            "atomic.__exit__(): STM not available")
     if not is_atomic():
-        raise OperationError(get_w_error(space),
-            space.wrap("atomic.__exit__(): more exits than enters"))
+        raise wrap_thread_error(space,
+            "atomic.__exit__(): more exits than enters")
     decrement_atomic()
diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -115,13 +115,16 @@
         self._lock = ll_lock
 
     def acquire(self, flag):
+        return self._acquire(flag)    # indirection for the STMLock subclass
+
+    def _acquire(self, flag):
         res = c_thread_acquirelock(self._lock, int(flag))
         res = rffi.cast(lltype.Signed, res)
         return bool(res)
 
     def release(self):
         # Sanity check: the lock must be locked
-        if self.acquire(False):
+        if self._acquire(False):
             c_thread_releaselock(self._lock)
             raise error("bad lock")
         else:
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -7,6 +7,7 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.error import OperationError
 
 # Force the declaration of the type 'thread.LockType' for RPython
 #import pypy.module.thread.rpython.exttable
@@ -32,9 +33,11 @@
     def __init__(self, space):
         self.space = space
         try:
-            self.lock = thread.allocate_lock()
-        except thread.error:
-            raise wrap_thread_error(space, "out of resources")
+            self.lock = space.allocate_lock()
+        except OperationError, e:
+            if e.match(space, space.w_RuntimeError):
+                raise wrap_thread_error(space, "out of resources")
+            raise
 
     @unwrap_spec(waitflag=int)
     def descr_lock_acquire(self, space, waitflag=1):
@@ -113,4 +116,4 @@
 def allocate_lock(space):
     """Create a new lock object.  (allocate() is an obsolete synonym.)
 See LockType.__doc__ for information about locks."""
-    return space.wrap(Lock(space))
\ No newline at end of file
+    return space.wrap(Lock(space))
diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py
--- a/pypy/module/thread/stm.py
+++ b/pypy/module/thread/stm.py
@@ -3,6 +3,8 @@
 """
 
 from pypy.module.thread.threadlocals import OSThreadLocals
+from pypy.module.thread.error import wrap_thread_error
+from pypy.module.thread import ll_thread
 from pypy.rlib import rstm
 from pypy.rlib.objectmodel import invoke_around_extcall
 
@@ -21,3 +23,18 @@
 
     def reinit_threads(self, space):
         self.setup_threads(space)
+
+
+class STMLock(ll_thread.Lock):
+    def __init__(self, space, ll_lock):
+        ll_thread.Lock.__init__(self, ll_lock)
+        self.space = space
+
+    def acquire(self, flag):
+        if rstm.is_atomic():
+            raise wrap_thread_error(self.space,
+                "cannot acquire locks inside an atomic block")
+        return ll_thread.Lock.acquire(self, flag)
+
+def allocate_stm_lock(space):
+    return STMLock(space, ll_thread.allocate_ll_lock())


More information about the pypy-commit mailing list