Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r58335:475f3eb6c7d7
Date: 2012-10-21 06:10 +0200
http://bitbucket.org/pypy/pypy/changeset/475f3eb6c7d7/

Log:    Add timeout to RLock.acquire()

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
@@ -31,6 +31,26 @@
 ##    sys.stderr.write(msg)
 
 
+def parse_acquire_args(space, blocking, timeout):
+    if not blocking and timeout != -1.0:
+        raise OperationError(space.w_ValueError, space.wrap(
+                "can't specify a timeout for a non-blocking call"))
+    if timeout < 0.0 and timeout != -1.0:
+        raise OperationError(space.w_ValueError, space.wrap(
+                "timeout value must be strictly positive"))
+    if not blocking:
+        microseconds = 0
+    elif timeout == -1.0:
+        microseconds = -1
+    else:
+        timeout *= 1e6
+        if timeout > float(TIMEOUT_MAX):
+            raise OperationError(space.w_ValueError, space.wrap(
+                    "timeout value is too large"))
+        microseconds = r_longlong(timeout)
+    return microseconds
+
+
 class Lock(Wrappable):
     "A wrappable box around an interp-level lock object."
 
@@ -49,22 +69,7 @@
 With an argument, this will only block if the argument is true,
 and the return value reflects whether the lock is acquired.
 The blocking operation is interruptible."""
-        if not blocking and timeout != -1.0:
-            raise OperationError(space.w_ValueError, space.wrap(
-                    "can't specify a timeout for a non-blocking call"))
-        if timeout < 0.0 and timeout != -1.0:
-            raise OperationError(space.w_ValueError, space.wrap(
-                    "timeout value must be strictly positive"))
-        if not blocking:
-            microseconds = 0
-        elif timeout == -1.0:
-            microseconds = -1
-        else:
-            timeout *= 1e6
-            if timeout > float(TIMEOUT_MAX):
-                raise OperationError(space.w_ValueError, space.wrap(
-                        "timeout value is too large"))
-            microseconds = r_longlong(timeout)
+        microseconds = parse_acquire_args(space, blocking, timeout)
         mylock = self.lock
         result = mylock.acquire_timed(microseconds)
         return space.newbool(result)
@@ -150,8 +155,8 @@
         return space.wrap("<%s owner=%d count=%d>" % (
                 typename, self.rlock_owner, self.rlock_count))
 
-    @unwrap_spec(blocking=bool)
-    def acquire_w(self, space, blocking=True):
+    @unwrap_spec(blocking=bool, timeout=float)
+    def acquire_w(self, space, blocking=True, timeout=-1.0):
         """Lock the lock.  `blocking` indicates whether we should wait
         for the lock to be available or not.  If `blocking` is False
         and another thread holds the lock, the method will return False
@@ -164,6 +169,7 @@
         Precisely, if the current thread already holds the lock, its
         internal counter is simply incremented. If nobody holds the lock,
         the lock is taken and its internal counter initialized to 1."""
+        microseconds = parse_acquire_args(space, blocking, timeout)
         tid = thread.get_ident()
         if self.rlock_count > 0 and tid == self.rlock_owner:
             try:
@@ -177,7 +183,7 @@
         if self.rlock_count > 0 or not self.lock.acquire(False):
             if not blocking:
                 return space.w_False
-            r = self.lock.acquire(True)
+            r = self.lock.acquire_timed(microseconds)
         if r:
             assert self.rlock_count == 0
             self.rlock_owner = tid
@@ -212,9 +218,12 @@
         else:
             return space.w_False
 
-    @unwrap_spec(count=int, owner=int)
-    def acquire_restore_w(self, space, count, owner):
+    def acquire_restore_w(self, space, w_saved_state):
         """For internal use by `threading.Condition`."""
+        # saved_state is the value returned by release_save()
+        w_count, w_owner = space.unpackiterable(w_saved_state, 2)
+        count = space.int_w(w_count)
+        owner = space.int_w(w_owner)
         r = True
         if not self.lock.acquire(False):
             r = self.lock.acquire(True)
diff --git a/pypy/module/thread/test/test_lock.py 
b/pypy/module/thread/test/test_lock.py
--- a/pypy/module/thread/test/test_lock.py
+++ b/pypy/module/thread/test/test_lock.py
@@ -128,3 +128,9 @@
         with lock:
             assert lock._is_owned() is True
 
+    def test_timeout(self):
+        import _thread
+        lock = _thread.RLock()
+        assert lock.acquire() is True
+        assert lock.acquire(False) is True
+        assert lock.acquire(True, timeout=.1) is True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to