Simply repository locking

This is a first pass at implementing repo locking. Next up, journal
recovery and undo.
This commit is contained in:
mpm@selenic.com 2005-05-26 08:53:04 -08:00
parent 0ccf847c00
commit 0058e326b8
2 changed files with 58 additions and 1 deletions

View File

@ -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 @@ class localrepository:
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 @@ class localrepository:
yield "".join([l, f, g])
def addchangegroup(self, generator):
self.lock()
class genread:
def __init__(self, generator):
self.g = generator

46
mercurial/lock.py Normal file
View File

@ -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)