Simply repository locking
This is a first pass at implementing repo locking. Next up, journal
recovery and undo.
--- a/mercurial/hg.py Wed May 25 16:40:22 2005 -0800
+++ b/mercurial/hg.py Thu May 26 08:53:04 2005 -0800
@@ -7,7 +7,7 @@
import sys, struct, sha, socket, os, time, re, urllib2
import urllib
-from mercurial import byterange
+from mercurial import byterange, lock
from mercurial.transaction import *
from mercurial.revlog import *
from difflib import SequenceMatcher
@@ -297,7 +297,17 @@
return transaction(self.opener, self.join("journal"),
self.join("undo"))
+ def lock(self, wait = 1):
+ 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 commit(self, parent, update = None, text = ""):
+ self.lock()
try:
remove = [ l[:-1] for l in self.opener("to-remove") ]
os.unlink(self.join("to-remove"))
@@ -612,6 +622,7 @@
yield "".join([l, f, g])
def addchangegroup(self, generator):
+ self.lock()
class genread:
def __init__(self, generator):
self.g = generator
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/lock.py Thu May 26 08:53:04 2005 -0800
@@ -0,0 +1,46 @@
+# lock.py - simple locking scheme for mercurial
+#
+# Copyright 2005 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+import os, time
+
+class LockHeld(Exception):
+ pass
+
+class lock:
+ def __init__(self, file, wait = 1):
+ self.f = file
+ self.held = 0
+ self.wait = wait
+ self.lock()
+
+ def __del__(self):
+ self.release()
+
+ def lock(self):
+ while 1:
+ try:
+ self.trylock()
+ return 1
+ except LockHeld, inst:
+ if self.wait:
+ time.sleep(1)
+ continue
+ raise inst
+
+ def trylock(self):
+ pid = os.getpid()
+ try:
+ os.symlink(str(pid), self.f)
+ self.held = 1
+ except:
+ raise LockHeld(os.readlink(self.f))
+
+ def release(self):
+ if self.held:
+ self.held = 0
+ os.unlink(self.f)
+