Rev 3479: (mbp) CountedLock support for lock tokens in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Fri Jun 6 08:08:16 BST 2008
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3479
revision-id:pqm at pqm.ubuntu.com-20080606070807-q0ro9i4kgllr5mbu
parent: pqm at pqm.ubuntu.com-20080605215009-3svreze778r0n4xv
parent: mbp at sourcefrog.net-20080605092259-keruhi6qrgf9ikax
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2008-06-06 08:08:07 +0100
message:
(mbp) CountedLock support for lock tokens
modified:
bzrlib/counted_lock.py counted_lock.py-20070502135927-7dk86io3ok7ctx6k-1
bzrlib/tests/test_counted_lock.py test_counted_lock.py-20070502135927-7dk86io3ok7ctx6k-2
bzrlib/tests/test_lockable_files.py test_lockable_files.py-20051225183927-365c7fd99591caf1
------------------------------------------------------------
revno: 3474.1.3
revision-id:mbp at sourcefrog.net-20080605092259-keruhi6qrgf9ikax
parent: mbp at sourcefrog.net-20080605075929-j5pet0dpcnj32r7x
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: countedlock
timestamp: Thu 2008-06-05 19:22:59 +1000
message:
CountedLock now handles and tests lock tokens
modified:
bzrlib/counted_lock.py counted_lock.py-20070502135927-7dk86io3ok7ctx6k-1
bzrlib/tests/test_counted_lock.py test_counted_lock.py-20070502135927-7dk86io3ok7ctx6k-2
------------------------------------------------------------
revno: 3474.1.2
revision-id:mbp at sourcefrog.net-20080605075929-j5pet0dpcnj32r7x
parent: mbp at sourcefrog.net-20080605064944-ky99sgxq3cg5gr38
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: countedlock
timestamp: Thu 2008-06-05 17:59:29 +1000
message:
CountedLock.unlock should raise LockNotHeld if appropriate
modified:
bzrlib/counted_lock.py counted_lock.py-20070502135927-7dk86io3ok7ctx6k-1
bzrlib/tests/test_counted_lock.py test_counted_lock.py-20070502135927-7dk86io3ok7ctx6k-2
------------------------------------------------------------
revno: 3474.1.1
revision-id:mbp at sourcefrog.net-20080605064944-ky99sgxq3cg5gr38
parent: pqm at pqm.ubuntu.com-20080605040505-i9kqxg2fps2qjdi0
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: countedlock
timestamp: Thu 2008-06-05 16:49:44 +1000
message:
Better reporting of inapplicable lockable_files tests
modified:
bzrlib/tests/test_lockable_files.py test_lockable_files.py-20051225183927-365c7fd99591caf1
=== modified file 'bzrlib/counted_lock.py'
--- a/bzrlib/counted_lock.py 2008-04-24 07:22:53 +0000
+++ b/bzrlib/counted_lock.py 2008-06-05 09:22:59 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Canonical Ltd
+# Copyright (C) 2007, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,17 +17,11 @@
"""Counted lock class"""
-from bzrlib.errors import (
- LockError,
- ReadOnlyError,
+from bzrlib import (
+ errors,
)
-# TODO: Pass through lock tokens on lock_write and read, and return them...
-#
-# TODO: Allow upgrading read locks to write? Conceptually difficult.
-
-
class CountedLock(object):
"""Decorator around a lock that makes it reentrant.
@@ -40,6 +34,10 @@
self._lock_mode = None
self._lock_count = 0
+ def __repr__(self):
+ return "%s(%r)" % (self.__class__.__name__,
+ self._real_lock)
+
def break_lock(self):
self._real_lock.break_lock()
self._lock_mode = None
@@ -62,22 +60,34 @@
self._lock_count = 1
self._lock_mode = 'r'
- def lock_write(self):
+ def lock_write(self, token=None):
"""Acquire the lock in write mode.
If the lock was originally acquired in read mode this will fail.
+
+ :param token: If non-None, reacquire the lock using this token.
"""
if self._lock_count == 0:
- self._real_lock.lock_write()
+ return_token = self._real_lock.lock_write(token)
self._lock_mode = 'w'
+ self._lock_count += 1
+ return return_token
elif self._lock_mode != 'w':
- raise ReadOnlyError(self)
- self._lock_count += 1
+ raise errors.ReadOnlyError(self)
+ else:
+ self._real_lock.validate_token(token)
+ self._lock_count += 1
+ return token
def unlock(self):
if self._lock_count == 0:
- raise LockError("%s not locked" % (self,))
+ raise errors.LockNotHeld(self)
elif self._lock_count == 1:
+ # these are decremented first; if we fail to unlock the most
+ # reasonable assumption is that we still don't have the lock
+ # anymore
+ self._lock_mode = None
+ self._lock_count -= 1
self._real_lock.unlock()
- self._lock_mode = None
- self._lock_count -= 1
+ else:
+ self._lock_count -= 1
=== modified file 'bzrlib/tests/test_counted_lock.py'
--- a/bzrlib/tests/test_counted_lock.py 2007-05-02 14:00:53 +0000
+++ b/bzrlib/tests/test_counted_lock.py 2008-06-05 09:22:59 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Canonical Ltd
+# Copyright (C) 2007, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,7 +19,9 @@
from bzrlib.counted_lock import CountedLock
from bzrlib.errors import (
LockError,
+ LockNotHeld,
ReadOnlyError,
+ TokenMismatch,
)
from bzrlib.tests import TestCase
@@ -39,10 +41,13 @@
self._lock_mode = 'r'
self._calls.append('lock_read')
- def lock_write(self):
+ def lock_write(self, token=None):
+ if token not in (None, 'token'):
+ raise TokenMismatch(token, 'token')
self._assert_not_locked()
self._lock_mode = 'w'
self._calls.append('lock_write')
+ return 'token'
def unlock(self):
self._assert_locked()
@@ -62,6 +67,15 @@
raise LockError("%s is already locked in mode %r" %
(self, self._lock_mode))
+ def validate_token(self, token):
+ if token == 'token':
+ # already held by this caller
+ return 'token'
+ elif token is None:
+ return
+ else:
+ raise TokenMismatch(token, 'token')
+
class TestDummyLock(TestCase):
@@ -131,7 +145,7 @@
def test_unlock_not_locked(self):
real_lock = DummyLock()
l = CountedLock(real_lock)
- self.assertRaises(LockError, l.unlock)
+ self.assertRaises(LockNotHeld, l.unlock)
def test_read_lock_while_write_locked(self):
real_lock = DummyLock()
=== modified file 'bzrlib/tests/test_lockable_files.py'
--- a/bzrlib/tests/test_lockable_files.py 2008-05-12 02:29:34 +0000
+++ b/bzrlib/tests/test_lockable_files.py 2008-06-05 06:49:44 +0000
@@ -27,7 +27,10 @@
from bzrlib.symbol_versioning import (
deprecated_in,
)
-from bzrlib.tests import TestCaseInTempDir
+from bzrlib.tests import (
+ TestCaseInTempDir,
+ TestNotApplicable,
+ )
from bzrlib.tests.test_smart import TestCaseWithSmartMedium
from bzrlib.tests.test_transactions import DummyWeave
from bzrlib.transactions import (PassThroughTransaction,
@@ -154,7 +157,7 @@
except NotImplementedError:
# this lock cannot be broken
self.lockable.unlock()
- return
+ raise TestNotApplicable("%r is not breakable" % (self.lockable,))
l2 = self.get_lockable()
orig_factory = bzrlib.ui.ui_factory
# silent ui - no need for stdout
@@ -177,7 +180,7 @@
if token is not None:
# This test does not apply, because this lockable supports
# tokens.
- return
+ raise TestNotApplicable("%r uses tokens" % (self.lockable,))
self.assertRaises(errors.TokenLockingNotSupported,
self.lockable.lock_write, token='token')
finally:
@@ -371,7 +374,10 @@
super(TestLockableFiles_TransportLock, self).tearDown()
# free the subtransport so that we do not get a 5 second
# timeout due to the SFTP connection cache.
- del self.sub_transport
+ try:
+ del self.sub_transport
+ except AttributeError:
+ pass
def get_lockable(self):
return LockableFiles(self.sub_transport, 'my-lock', TransportLock)
More information about the bazaar-commits
mailing list