[pypy-commit] pypy default: Yet another attempt to unravel the mess that 6dac6407412f exposed.

arigo noreply at buildbot.pypy.org
Wed Apr 16 13:11:08 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r70650:867cc494a9fa
Date: 2014-04-16 11:10 +0000
http://bitbucket.org/pypy/pypy/changeset/867cc494a9fa/

Log:	Yet another attempt to unravel the mess that 6dac6407412f exposed.
	This makes space.allocate_lock() raise CannotHaveLock if we're
	translating. Translation passes again.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -337,6 +337,9 @@
         return 'internal subclass of %s' % (Class.__name__,)
 wrappable_class_name._annspecialcase_ = 'specialize:memo'
 
+class CannotHaveLock(Exception):
+    """Raised by space.allocate_lock() if we're translating."""
+
 # ____________________________________________________________
 
 class ObjSpace(object):
@@ -663,6 +666,11 @@
 
     def __allocate_lock(self):
         from rpython.rlib.rthread import allocate_lock, error
+        # hack: we can't have prebuilt locks if we're translating.
+        # In this special situation we should just not lock at all
+        # (translation is not multithreaded anyway).
+        if not we_are_translated() and self.config.translating:
+            raise CannotHaveLock()
         try:
             return allocate_lock()
         except error:
diff --git a/pypy/module/_file/interp_stream.py b/pypy/module/_file/interp_stream.py
--- a/pypy/module/_file/interp_stream.py
+++ b/pypy/module/_file/interp_stream.py
@@ -4,7 +4,7 @@
 from rpython.rlib.streamio import StreamErrors
 
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.baseobjspace import ObjSpace, W_Root
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, CannotHaveLock
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.streamutil import wrap_streamerror, wrap_oserror_as_ioerror
@@ -33,19 +33,24 @@
     def _try_acquire_lock(self):
         # this function runs with the GIL acquired so there is no race
         # condition in the creation of the lock
-        if self.slock is None:
-            self.slock = self.space.allocate_lock()
         me = self.space.getexecutioncontext()   # used as thread ident
         if self.slockowner is me:
             return False    # already acquired by the current thread
-        self.slock.acquire(True)
+        try:
+            if self.slock is None:
+                self.slock = self.space.allocate_lock()
+        except CannotHaveLock:
+            pass
+        else:
+            self.slock.acquire(True)
         assert self.slockowner is None
         self.slockowner = me
         return True
 
     def _release_lock(self):
         self.slockowner = None
-        self.slock.release()
+        if self.slock is not None:
+            self.slock.release()
 
     def lock(self):
         if not self._try_acquire_lock():
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -8,7 +8,7 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, generic_new_descr
 from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.baseobjspace import W_Root, CannotHaveLock
 from pypy.interpreter.eval import Code
 from pypy.interpreter.pycode import PyCode
 from rpython.rlib import streamio, jit
@@ -753,26 +753,14 @@
         me = self.space.getexecutioncontext()   # used as thread ident
         return self.lockowner is me
 
-    def _can_have_lock(self):
-        # hack: we can't have self.lock != None during translation,
-        # because prebuilt lock objects are not allowed.  In this
-        # special situation we just don't lock at all (translation is
-        # not multithreaded anyway).
-        if we_are_translated():
-            return True     # we need a lock at run-time
-        elif self.space.config.translating:
-            assert self.lock is None
-            return False
-        else:
-            return True     # in py.py
-
     def acquire_lock(self):
         # this function runs with the GIL acquired so there is no race
         # condition in the creation of the lock
         if self.lock is None:
-            if not self._can_have_lock():
+            try:
+                self.lock = self.space.allocate_lock()
+            except CannotHaveLock:
                 return
-            self.lock = self.space.allocate_lock()
         me = self.space.getexecutioncontext()   # used as thread ident
         if self.lockowner is me:
             pass    # already acquired by the current thread
@@ -790,7 +778,7 @@
                 # Too bad.  This situation can occur if a fork() occurred
                 # with the import lock held, and we're the child.
                 return
-            if not self._can_have_lock():
+            if self.lock is None:   # CannotHaveLock occurred
                 return
             space = self.space
             raise OperationError(space.w_RuntimeError,
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -153,6 +153,9 @@
     def __exit__(self, *args):
         self.release()
 
+    def _cleanup_(self):
+        raise Exception("seeing a prebuilt rpython.rlib.rthread.Lock instance")
+
 # ____________________________________________________________
 #
 # Stack size


More information about the pypy-commit mailing list