locking: Don't schedule pending acq. for short timeout
authorMichael Hanselmann <hansmi@google.com>
Fri, 16 Nov 2012 16:43:50 +0000 (17:43 +0100)
committerMichael Hanselmann <hansmi@google.com>
Mon, 19 Nov 2012 13:10:23 +0000 (14:10 +0100)
Scheduling a pending acquisition is relatively expensive and lot of code
is involved. Unless there is already one, a new pipe needs to be opened.
Data structures need to be updated as well, only to be undone shortly
after. This patch adds a small condition to return straight away if the
timeout is shorter than 1ms and the lock couldn't be acquired right
away. Blocking acquisitions are not affected, as are acquisitions with
longer timeouts.

While I tried hard, I could not find a way of writing a test
specifically for this case which wouldn't have involved making
significant other modifications. Other tests already exercise the new
code, though.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>

lib/locking.py

index 74f1702..014b378 100644 (file)
@@ -47,6 +47,10 @@ _DELETED_TEXT = "deleted"
 
 _DEFAULT_PRIORITY = 0
 
+#: Minimum timeout required to consider scheduling a pending acquisition
+#: (seconds)
+_LOCK_ACQUIRE_MIN_TIMEOUT = (1.0 / 1000)
+
 
 def ssynchronized(mylock, shared=0):
   """Shared Synchronization decorator.
@@ -662,6 +666,12 @@ class SharedLock(object):
       self.__do_acquire(shared)
       return True
 
+    # The lock couldn't be acquired right away, so if a timeout is given and is
+    # considered too short, return right away as scheduling a pending
+    # acquisition is quite expensive
+    if timeout is not None and timeout < _LOCK_ACQUIRE_MIN_TIMEOUT:
+      return False
+
     prioqueue = self.__pending_by_prio.get(priority, None)
 
     if shared: