[PATCH] add a timeout when a lock is held

Benoit Boissinot benoit.boissinot at ens-lyon.org
Tue Jan 31 09:44:14 UTC 2006


# HG changeset patch
# User Benoit Boissinot <benoit.boissinot at ens-lyon.org>
# Node ID 665cf29e7c7eacd5cd190134e0dcf18a9eec62d9
# Parent  f4dd1f50cc236ce8c7f86b0e9583d271669e90d5
add a timeout when a lock is held (default 1024 sec)

- change the wait keyword from lock.lock to timeout,
  a negative timeout of means "wait forever"
- refactor the two lock functions from localrepo.py
- make them use the timeout (default 1024, can be changed
  with ui.timeout in the config file
- update the doc

diff -r f4dd1f50cc23 -r 665cf29e7c7e doc/hgrc.5.txt
--- a/doc/hgrc.5.txt	Mon Jan 30 08:56:39 2006 +0100
+++ b/doc/hgrc.5.txt	Tue Jan 31 10:17:41 2006 +0100
@@ -192,6 +192,9 @@ ui::
     remote command to use for clone/push/pull operations. Default is 'hg'.
   ssh;;
     command to use for SSH connections. Default is 'ssh'.
+  timeout;;
+    The timeout used when a lock is held (in seconds), a negative value
+    means no timeout. Default is 1024.
   username;;
     The committer of a changeset created when running "commit".
     Typically a person's name and email address, e.g. "Fred Widget
diff -r f4dd1f50cc23 -r 665cf29e7c7e mercurial/localrepo.py
--- a/mercurial/localrepo.py	Mon Jan 30 08:56:39 2006 +0100
+++ b/mercurial/localrepo.py	Tue Jan 31 10:17:41 2006 +0100
@@ -247,25 +247,31 @@ class localrepository(object):
         else:
             self.ui.warn(_("no undo information available\n"))
 
-    def lock(self, wait=1):
+    def __lock(self, wait, name, acquirefn=None, releasefn=None):
         try:
-            return lock.lock(self.join("lock"), 0)
-        except lock.LockHeld, inst:
-            if wait:
-                self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0])
-                return lock.lock(self.join("lock"), wait)
-            raise inst
-
-    def wlock(self, wait=1):
-        try:
-            wlock = lock.lock(self.join("wlock"), 0, self.dirstate.write)
+            __lock = lock.lock(name, 0, releasefn)
         except lock.LockHeld, inst:
             if not wait:
                 raise inst
             self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0])
-            wlock = lock.lock(self.join("wlock"), wait, self.dirstate.write)
-        self.dirstate.read()
-        return wlock
+            try:
+                # default to 1024 seconds timeout
+                __lock = lock.lock(name,
+                                   int(self.ui.config("ui", "timeout") or 1024),
+                                   releasefn)
+            except lock.LockHeld, inst:
+                raise util.Abort(_("timeout while waiting for "
+                                   "lock held by %s") % inst.args[0])
+        if acquirefn is not None:
+            acquirefn()
+        return __lock
+
+    def lock(self, wait=1):
+        return self.__lock(wait, self.join("lock"))
+
+    def wlock(self, wait=1):
+        return self.__lock(wait, self.join("wlock"),
+                           self.dirstate.read, self.dirstate.write)
 
     def rawcommit(self, files, text, user, date, p1=None, p2=None):
         orig_parent = self.dirstate.parents()[0] or nullid
diff -r f4dd1f50cc23 -r 665cf29e7c7e mercurial/lock.py
--- a/mercurial/lock.py	Mon Jan 30 08:56:39 2006 +0100
+++ b/mercurial/lock.py	Tue Jan 31 10:17:41 2006 +0100
@@ -12,10 +12,10 @@ class LockHeld(Exception):
     pass
 
 class lock(object):
-    def __init__(self, file, wait=1, releasefn=None):
+    def __init__(self, file, timeout=-1, releasefn=None):
         self.f = file
         self.held = 0
-        self.wait = wait
+        self.timeout = timeout
         self.releasefn = releasefn
         self.lock()
 
@@ -23,13 +23,16 @@ class lock(object):
         self.release()
 
     def lock(self):
+        timeout = self.timeout
         while 1:
             try:
                 self.trylock()
                 return 1
             except LockHeld, inst:
-                if self.wait:
+                if timeout != 0:
                     time.sleep(1)
+                    if timeout > 0:
+                        timeout -= 1
                     continue
                 raise inst
 



More information about the Mercurial mailing list