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 sys, struct, sha, socket, os, time, re, urllib2
import urllib import urllib
from mercurial import byterange from mercurial import byterange, lock
from mercurial.transaction import * from mercurial.transaction import *
from mercurial.revlog import * from mercurial.revlog import *
from difflib import SequenceMatcher from difflib import SequenceMatcher
@ -297,7 +297,17 @@ class localrepository:
return transaction(self.opener, self.join("journal"), return transaction(self.opener, self.join("journal"),
self.join("undo")) 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 = ""): def commit(self, parent, update = None, text = ""):
self.lock()
try: try:
remove = [ l[:-1] for l in self.opener("to-remove") ] remove = [ l[:-1] for l in self.opener("to-remove") ]
os.unlink(self.join("to-remove")) os.unlink(self.join("to-remove"))
@ -612,6 +622,7 @@ class localrepository:
yield "".join([l, f, g]) yield "".join([l, f, g])
def addchangegroup(self, generator): def addchangegroup(self, generator):
self.lock()
class genread: class genread:
def __init__(self, generator): def __init__(self, generator):
self.g = 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)