Comments
Patch
@@ -9,7 +9,18 @@
import errno, os, socket, time
import warnings
-class lock(object):
+class abstractlock(object):
+ '''define that interface that all lock classes must follow'''
+ def lock(self):
+ raise NotImplementedError('abstract method')
+ def trylock(self):
+ raise NotImplementedError('abstract method')
+ def testlock(self):
+ raise NotImplementedError('abstract method')
+ def release(self):
+ raise NotImplementedError('abstract method')
+
+class lock(abstractlock):
'''An advisory lock held by one process to control access to a set
of files. Non-cooperating processes or incorrectly written scripts
can ignore Mercurial's locking scheme and stomp all over the
@@ -150,6 +161,41 @@
for callback in self.postrelease:
callback()
+class multilock(abstractlock):
+ """a group of locks that behave as one"""
+ def __init__(self, *locks):
+ self.locks = locks
+
+ def __del__(self):
+ for l in reversed(self.locks):
+ del l
+ self.locks = []
+
+ def lock(self):
+ for l in self.locks:
+ l.lock()
+
+ def trylock(self):
+ for l in self.locks:
+ l.trylock()
+
+ def testlock(self):
+ """return id of first valid lock, else None"""
+ for l in self.locks:
+ res = l.testlock()
+ if res is not None:
+ return res
+ return None
+
+ def release(self):
+ """release all locks executing their callback functions if any"""
+ for l in reversed(self.locks):
+ l.release()
+
+ @property
+ def held(self):
+ return max([l.held for l in self.locks])
+
def release(*locks):
for lock in locks:
if lock is not None: