File locking
Lukáš Lalinský
lalinsky at gmail.com
Sat Sep 8 11:23:29 BST 2007
Hi,
I'm trying to fix the Windows file locking issues, but after playing
with it a little I'm starting to think that's the fcntl locking
implementation the one that is wrong and that there are some serious
locking issues inside bzrlib. If I understand it correctly, acquiring
read lock on a file, while write lock is held, should fail, because the
process would be then allowed to read file in inconsistent state. But if
I do this on Linux, I get no errors:
>>> from bzrlib import lock
>>> a = lock.WriteLock('.bzr/checkout/dirstate')
>>> b = lock.ReadLock('.bzr/checkout/dirstate')
If I do the same with the WinAPI implementation, it correctly fails:
>>> from bzrlib import lock
>>> a = lock.WriteLock('.bzr/checkout/dirstate')
>>> b = lock.ReadLock('.bzr/checkout/dirstate')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "Z:\home\lukas\projects\bzr\bzr\win32-fixes\bzrlib\lock.py", line
303, in __init__
self._lock(filename, 'rb', LOCK_SH + LOCK_NB)
File "Z:\home\lukas\projects\bzr\bzr\win32-fixes\bzrlib\lock.py", line
279, in _lock
raise errors.LockContention(filename)
bzrlib.errors.LockContention: Could not acquire lock
".bzr/checkout/dirstate"
So I started looking more into the fcntl-based file locking on Linux:
>>> import fcntl
>>> a = open('.bzr/checkout/dirstate', 'rb+')
>>> b = open('.bzr/checkout/dirstate', 'rb+')
>>> fcntl.lockf(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.lockf(b, fcntl.LOCK_SH | fcntl.LOCK_NB) # no IOError
>>> fcntl.lockf(b, fcntl.LOCK_EX | fcntl.LOCK_NB) # still no IOError!
But using flock it seems to work correctly:
>>> import fcntl
>>> a = open('.bzr/checkout/dirstate', 'rb+')
>>> b = open('.bzr/checkout/dirstate', 'rb+')
>>> fcntl.flock(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.flock(b, fcntl.LOCK_SH | fcntl.LOCK_NB)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 11] Resource temporarily unavailable
Frankly, I don't know much about Linux internals, but after these tests
does fcntl.lockf look 'no-op' to me. I see that bzrlib.locks handles
some locking internally by _fcntl_WriteLock._open_locks and
_fcntl_ReadLock._open_locks, but this of course doesn't cover the case
of EX+SH locks, multiple running instances of bzr, and will produce very
strange results if somebody will try to use bzrlib in a threaded (since
bzrlib is blocking...) GUI application.
So my question is, does fcntl.lockf actually do something and does this
code:
except IOError, e:
if e.errno in (errno.EAGAIN, errno.EACCES):
# We couldn't grab the lock
self.unlock()
# we should be more precise about whats a locking
# error and whats a random-other error
raise errors.LockContention(e)
have some test coverage? And finally, am I correct in thinking that a
try to acquire read lock for a file that is already write-locked should
fail?
Lukas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Toto je =?ISO-8859-1?Q?digit=E1lne?=
=?ISO-8859-1?Q?_podp=EDsan=E1?= =?UTF-8?Q?_=C4=8Das=C5=A5?=
=?ISO-8859-1?Q?_spr=E1vy?=
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20070908/a6ae0d22/attachment.pgp
More information about the bazaar
mailing list