/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.5 by John Arbash Meinel
Merge bzr.dev 5021 to resolve NEWS
1
# Copyright (C) 2005-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
577 by Martin Pool
- merge portable lock module from John
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
577 by Martin Pool
- merge portable lock module from John
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
577 by Martin Pool
- merge portable lock module from John
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
577 by Martin Pool
- merge portable lock module from John
16
1553.5.39 by Martin Pool
More lock docs
17
"""Locking using OS file locks or file existence.
577 by Martin Pool
- merge portable lock module from John
18
1553.5.46 by Martin Pool
doc
19
Note: This method of locking is generally deprecated in favour of LockDir, but
20
is used to lock local WorkingTrees, and by some old formats.  It's accessed
21
through Transport.lock_read(), etc.
577 by Martin Pool
- merge portable lock module from John
22
23
This module causes two methods, lock() and unlock() to be defined in
24
any way that works on the current platform.
25
26
It is not specified whether these locks are reentrant (i.e. can be
27
taken repeatedly by a single process) or whether they exclude
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
28
different threads in a single process.  That reentrancy is provided by
1553.5.39 by Martin Pool
More lock docs
29
LockableFiles.
615 by Martin Pool
Major rework of locking code:
30
31
This defines two classes: ReadLock and WriteLock, which can be
32
implemented in different ways on different platforms.  Both have an
33
unlock() method.
614 by Martin Pool
- unify two defintions of LockError
34
"""
577 by Martin Pool
- merge portable lock module from John
35
6538.1.11 by Aaron Bentley
Switch to much simpler implementation of restore_uncommitted.
36
import contextlib
1185.65.29 by Robert Collins
Implement final review suggestions.
37
import errno
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
38
import os
2353.3.12 by John Arbash Meinel
Don't create the alternative lock types unless we are on windows.
39
import sys
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
40
import warnings
577 by Martin Pool
- merge portable lock module from John
41
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
42
from . import (
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
43
    debug,
2353.3.11 by John Arbash Meinel
Code cleanup
44
    errors,
45
    osutils,
46
    trace,
47
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
48
from .hooks import Hooks
49
from .i18n import gettext
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
50
7143.15.2 by Jelmer Vernooij
Run autopep8.
51
3724.1.1 by Martin Pool
Move Lock hooks onto a base Lock class and make them more consistent with other lock classes
52
class LockHooks(Hooks):
53
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
54
    def __init__(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
55
        Hooks.__init__(self, "breezy.lock", "Lock.hooks")
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
56
        self.add_hook(
57
            'lock_acquired',
58
            "Called with a breezy.lock.LockResult when a physical lock is "
59
            "acquired.", (1, 8))
60
        self.add_hook(
61
            'lock_released',
62
            "Called with a breezy.lock.LockResult when a physical lock is "
63
            "released.", (1, 8))
64
        self.add_hook(
65
            'lock_broken',
66
            "Called with a breezy.lock.LockResult when a physical lock is "
67
            "broken.", (1, 15))
3724.1.1 by Martin Pool
Move Lock hooks onto a base Lock class and make them more consistent with other lock classes
68
69
70
class Lock(object):
71
    """Base class for locks.
72
73
    :cvar hooks: Hook dictionary for operations on locks.
74
    """
75
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
76
    hooks = LockHooks()
3724.1.1 by Martin Pool
Move Lock hooks onto a base Lock class and make them more consistent with other lock classes
77
78
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
79
class LockResult(object):
3331.3.5 by Martin Pool
Move physical lock hooks onto new PhysicalLock class variable
80
    """Result of an operation on a lock; passed to a hook"""
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
81
3331.3.2 by Robert Collins
Polish on lock hooks to be easier to use.
82
    def __init__(self, lock_url, details=None):
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
83
        """Create a lock result for lock with optional details about the lock."""
3331.3.2 by Robert Collins
Polish on lock hooks to be easier to use.
84
        self.lock_url = lock_url
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
85
        self.details = details
86
87
    def __eq__(self, other):
3331.3.2 by Robert Collins
Polish on lock hooks to be easier to use.
88
        return self.lock_url == other.lock_url and self.details == other.details
1711.8.1 by John Arbash Meinel
Branch.lock_read/lock_write/unlock should handle failures
89
4327.1.1 by Vincent Ladeuil
Start addressing test failing when run with -Dlock.
90
    def __repr__(self):
4634.146.9 by Danny van Heumen
Changed representation of LockResult: separate path and nonce with a comma.
91
        return '%s(%s, %s)' % (self.__class__.__name__,
7143.15.2 by Jelmer Vernooij
Run autopep8.
92
                               self.lock_url, self.details)
4327.1.1 by Vincent Ladeuil
Start addressing test failing when run with -Dlock.
93
577 by Martin Pool
- merge portable lock module from John
94
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
95
class LogicalLockResult(object):
96
    """The result of a lock_read/lock_write/lock_tree_write call on lockables.
97
98
    :ivar unlock: A callable which will unlock the lock.
99
    """
100
6754.8.4 by Jelmer Vernooij
Use new context stuff.
101
    def __init__(self, unlock, token=None):
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
102
        self.unlock = unlock
6754.8.4 by Jelmer Vernooij
Use new context stuff.
103
        self.token = token
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
104
105
    def __repr__(self):
106
        return "LogicalLockResult(%s)" % (self.unlock)
107
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
108
    def __enter__(self):
6754.8.9 by Jelmer Vernooij
Fix more tests.
109
        return self
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
110
111
    def __exit__(self, exc_type, exc_val, exc_tb):
6754.8.12 by Jelmer Vernooij
FIx remaining tests.
112
        # If there was an error raised, prefer the original one
113
        try:
114
            self.unlock()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
115
        except BaseException:
6754.8.12 by Jelmer Vernooij
FIx remaining tests.
116
            if exc_type is None:
117
                raise
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
118
        return False
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
119
120
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
121
def cant_unlock_not_held(locked_object):
122
    """An attempt to unlock failed because the object was not locked.
123
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
124
    This provides a policy point from which we can generate either a warning or
125
    an exception.
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
126
    """
127
    # This is typically masking some other error and called from a finally
4509.3.36 by Martin Pool
Review cleanups of typos and unneeded imports
128
    # block, so it's useful to have the option not to generate a new error
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
129
    # here.  You can use -Werror to make it fatal.  It should possibly also
130
    # raise LockNotHeld.
4509.3.27 by Martin Pool
Change debug flag to -Dunlock and document it
131
    if 'unlock' in debug.debug_flags:
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
132
        warnings.warn("%r is already unlocked" % (locked_object,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
133
                      stacklevel=3)
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
134
    else:
135
        raise errors.LockNotHeld(locked_object)
136
137
3224.5.32 by Andrew Bennetts
Tidy conditional imports in bzrlib/lock.py as suggested by John's review.
138
try:
139
    import fcntl
140
    have_fcntl = True
141
except ImportError:
142
    have_fcntl = False
143
144
have_ctypes_win32 = False
145
if sys.platform == 'win32':
146
    import msvcrt
147
    try:
148
        import ctypes
149
        have_ctypes_win32 = True
150
    except ImportError:
151
        pass
152
153
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
154
class _OSLock(object):
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
155
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
156
    def __init__(self):
157
        self.f = None
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
158
        self.filename = None
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
159
615 by Martin Pool
Major rework of locking code:
160
    def _open(self, filename, filemode):
2353.3.11 by John Arbash Meinel
Code cleanup
161
        self.filename = osutils.realpath(filename)
656 by Martin Pool
- create branch lock files if they don't exist
162
        try:
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
163
            self.f = open(self.filename, filemode)
656 by Martin Pool
- create branch lock files if they don't exist
164
            return self.f
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
165
        except IOError as e:
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
166
            if e.errno in (errno.EACCES, errno.EPERM):
2872.5.1 by Martin Pool
Avoid internal error tracebacks on failure to lock on readonly transport (#129701).
167
                raise errors.LockFailed(self.filename, str(e))
656 by Martin Pool
- create branch lock files if they don't exist
168
            if e.errno != errno.ENOENT:
169
                raise
170
171
            # maybe this is an old branch (before may 2005)
2353.3.11 by John Arbash Meinel
Code cleanup
172
            trace.mutter("trying to create missing lock %r", self.filename)
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
173
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
174
            self.f = open(self.filename, 'wb+')
656 by Martin Pool
- create branch lock files if they don't exist
175
            return self.f
176
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
177
    def _clear_f(self):
178
        """Clear the self.f attribute cleanly."""
179
        if self.f:
180
            self.f.close()
181
            self.f = None
182
615 by Martin Pool
Major rework of locking code:
183
    def unlock(self):
184
        raise NotImplementedError()
185
186
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
187
_lock_classes = []
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
188
189
190
if have_fcntl:
615 by Martin Pool
Major rework of locking code:
191
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
192
    class _fcntl_FileLock(_OSLock):
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
193
194
        def _unlock(self):
1185.9.2 by Harald Meland
Use fcntl.lockf() rather than fcntl.flock() to support NFS file systems.
195
            fcntl.lockf(self.f, fcntl.LOCK_UN)
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
196
            self._clear_f()
197
615 by Martin Pool
Major rework of locking code:
198
    class _fcntl_WriteLock(_fcntl_FileLock):
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
199
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
200
        _open_locks = set()
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
201
615 by Martin Pool
Major rework of locking code:
202
        def __init__(self, filename):
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
203
            super(_fcntl_WriteLock, self).__init__()
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
204
            # Check we can grab a lock before we actually open the file.
205
            self.filename = osutils.realpath(filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
206
            if self.filename in _fcntl_WriteLock._open_locks:
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
207
                self._clear_f()
208
                raise errors.LockContention(self.filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
209
            if self.filename in _fcntl_ReadLock._open_locks:
4523.4.10 by John Arbash Meinel
Update the various documentation and use strict_locks instead of strict-locks.
210
                if 'strict_locks' in debug.debug_flags:
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
211
                    self._clear_f()
212
                    raise errors.LockContention(self.filename)
213
                else:
214
                    trace.mutter('Write lock taken w/ an open read lock on: %s'
215
                                 % (self.filename,))
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
216
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
217
            self._open(self.filename, 'rb+')
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
218
            # reserve a slot for this lock - even if the lockf call fails,
5009.1.1 by Vincent Ladeuil
(trivial) Fix typos
219
            # at this point unlock() will be called, because self.f is set.
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
220
            # TODO: make this fully threadsafe, if we decide we care.
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
221
            _fcntl_WriteLock._open_locks.add(self.filename)
615 by Martin Pool
Major rework of locking code:
222
            try:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
223
                # LOCK_NB will cause IOError to be raised if we can't grab a
224
                # lock right away.
225
                fcntl.lockf(self.f, fcntl.LOCK_EX | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
226
            except IOError as e:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
227
                if e.errno in (errno.EAGAIN, errno.EACCES):
228
                    # We couldn't grab the lock
229
                    self.unlock()
1185.65.29 by Robert Collins
Implement final review suggestions.
230
                # we should be more precise about whats a locking
231
                # error and whats a random-other error
4100.1.4 by Martin Pool
LockContention on OS locks now includes the filename
232
                raise errors.LockContention(self.filename, e)
615 by Martin Pool
Major rework of locking code:
233
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
234
        def unlock(self):
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
235
            _fcntl_WriteLock._open_locks.remove(self.filename)
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
236
            self._unlock()
237
615 by Martin Pool
Major rework of locking code:
238
    class _fcntl_ReadLock(_fcntl_FileLock):
1185.65.29 by Robert Collins
Implement final review suggestions.
239
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
240
        _open_locks = {}
2353.3.3 by John Arbash Meinel
Define an explicit error when trying to grab a write lock on a readonly file.
241
2353.4.11 by John Arbash Meinel
Remove the unused _ignore_write_lock parameter.
242
        def __init__(self, filename):
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
243
            super(_fcntl_ReadLock, self).__init__()
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
244
            self.filename = osutils.realpath(filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
245
            if self.filename in _fcntl_WriteLock._open_locks:
4523.4.10 by John Arbash Meinel
Update the various documentation and use strict_locks instead of strict-locks.
246
                if 'strict_locks' in debug.debug_flags:
4523.4.14 by John Arbash Meinel
Fix the direct lock tests.
247
                    # We raise before calling _open so we don't need to
248
                    # _clear_f
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
249
                    raise errors.LockContention(self.filename)
250
                else:
251
                    trace.mutter('Read lock taken w/ an open write lock on: %s'
252
                                 % (self.filename,))
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
253
            _fcntl_ReadLock._open_locks.setdefault(self.filename, 0)
254
            _fcntl_ReadLock._open_locks[self.filename] += 1
1185.65.29 by Robert Collins
Implement final review suggestions.
255
            self._open(filename, 'rb')
615 by Martin Pool
Major rework of locking code:
256
            try:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
257
                # LOCK_NB will cause IOError to be raised if we can't grab a
258
                # lock right away.
259
                fcntl.lockf(self.f, fcntl.LOCK_SH | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
260
            except IOError as e:
1185.65.29 by Robert Collins
Implement final review suggestions.
261
                # we should be more precise about whats a locking
262
                # error and whats a random-other error
4100.1.4 by Martin Pool
LockContention on OS locks now includes the filename
263
                raise errors.LockContention(self.filename, e)
615 by Martin Pool
Major rework of locking code:
264
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
265
        def unlock(self):
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
266
            count = _fcntl_ReadLock._open_locks[self.filename]
267
            if count == 1:
268
                del _fcntl_ReadLock._open_locks[self.filename]
269
            else:
270
                _fcntl_ReadLock._open_locks[self.filename] = count - 1
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
271
            self._unlock()
272
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
273
        def temporary_write_lock(self):
274
            """Try to grab a write lock on the file.
275
276
            On platforms that support it, this will upgrade to a write lock
277
            without unlocking the file.
278
            Otherwise, this will release the read lock, and try to acquire a
279
            write lock.
280
281
            :return: A token which can be used to switch back to a read lock.
282
            """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
283
            if self.filename in _fcntl_WriteLock._open_locks:
284
                raise AssertionError('file already locked: %r'
7143.15.2 by Jelmer Vernooij
Run autopep8.
285
                                     % (self.filename,))
2353.4.7 by John Arbash Meinel
Change the temporary_write_lock api, so that it always returns a lock object,
286
            try:
287
                wlock = _fcntl_TemporaryWriteLock(self)
288
            except errors.LockError:
289
                # We didn't unlock, so we can just return 'self'
290
                return False, self
291
            return True, wlock
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
292
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
293
    class _fcntl_TemporaryWriteLock(_OSLock):
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
294
        """A token used when grabbing a temporary_write_lock.
295
296
        Call restore_read_lock() when you are done with the write lock.
297
        """
298
299
        def __init__(self, read_lock):
300
            super(_fcntl_TemporaryWriteLock, self).__init__()
301
            self._read_lock = read_lock
302
            self.filename = read_lock.filename
303
304
            count = _fcntl_ReadLock._open_locks[self.filename]
305
            if count > 1:
306
                # Something else also has a read-lock, so we cannot grab a
307
                # write lock.
308
                raise errors.LockContention(self.filename)
309
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
310
            if self.filename in _fcntl_WriteLock._open_locks:
311
                raise AssertionError('file already locked: %r'
7143.15.2 by Jelmer Vernooij
Run autopep8.
312
                                     % (self.filename,))
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
313
314
            # See if we can open the file for writing. Another process might
315
            # have a read lock. We don't use self._open() because we don't want
316
            # to create the file if it exists. That would have already been
317
            # done by _fcntl_ReadLock
318
            try:
319
                new_f = open(self.filename, 'rb+')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
320
            except IOError as e:
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
321
                if e.errno in (errno.EACCES, errno.EPERM):
2872.5.1 by Martin Pool
Avoid internal error tracebacks on failure to lock on readonly transport (#129701).
322
                    raise errors.LockFailed(self.filename, str(e))
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
323
                raise
324
            try:
325
                # LOCK_NB will cause IOError to be raised if we can't grab a
326
                # lock right away.
2379.3.1 by John Arbash Meinel
Cherry-pick the 2 locking fixes from the 0.15 branch.
327
                fcntl.lockf(new_f, fcntl.LOCK_EX | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
328
            except IOError as e:
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
329
                # TODO: Raise a more specific error based on the type of error
4100.1.4 by Martin Pool
LockContention on OS locks now includes the filename
330
                raise errors.LockContention(self.filename, e)
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
331
            _fcntl_WriteLock._open_locks.add(self.filename)
332
333
            self.f = new_f
334
335
        def restore_read_lock(self):
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
336
            """Restore the original ReadLock."""
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
337
            # For fcntl, since we never released the read lock, just release
338
            # the write lock, and return the original lock.
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
339
            fcntl.lockf(self.f, fcntl.LOCK_UN)
340
            self._clear_f()
341
            _fcntl_WriteLock._open_locks.remove(self.filename)
342
            # Avoid reference cycles
343
            read_lock = self._read_lock
344
            self._read_lock = None
345
            return read_lock
346
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
347
    _lock_classes.append(('fcntl', _fcntl_WriteLock, _fcntl_ReadLock))
577 by Martin Pool
- merge portable lock module from John
348
2353.3.11 by John Arbash Meinel
Code cleanup
349
3224.5.1 by Andrew Bennetts
Lots of assorted hackery to reduce the number of imports for common operations. Improves 'rocks', 'st' and 'help' times by ~50ms on my laptop.
350
if have_ctypes_win32:
7143.11.1 by Jelmer Vernooij
Remove some unused imports.
351
    from ctypes.wintypes import DWORD, LPWSTR
7143.15.2 by Jelmer Vernooij
Run autopep8.
352
    LPSECURITY_ATTRIBUTES = ctypes.c_void_p  # used as NULL no need to declare
353
    HANDLE = ctypes.c_int  # rather than unsigned as in ctypes.wintypes
6658.6.1 by Martin
Remove winver, win98 support code, and deprecated code
354
    _function_name = "CreateFileW"
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
355
356
    # CreateFile <http://msdn.microsoft.com/en-us/library/aa363858.aspx>
357
    _CreateFile = ctypes.WINFUNCTYPE(
7143.15.2 by Jelmer Vernooij
Run autopep8.
358
        HANDLE,                # return value
359
        LPWSTR,                # lpFileName
360
        DWORD,                 # dwDesiredAccess
361
        DWORD,                 # dwShareMode
362
        LPSECURITY_ATTRIBUTES,  # lpSecurityAttributes
363
        DWORD,                 # dwCreationDisposition
364
        DWORD,                 # dwFlagsAndAttributes
365
        HANDLE                 # hTemplateFile
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
366
        )((_function_name, ctypes.windll.kernel32))
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
367
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
368
    INVALID_HANDLE_VALUE = -1
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
369
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
370
    GENERIC_READ = 0x80000000
371
    GENERIC_WRITE = 0x40000000
372
    FILE_SHARE_READ = 1
373
    OPEN_ALWAYS = 4
374
    FILE_ATTRIBUTE_NORMAL = 128
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
375
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
376
    ERROR_ACCESS_DENIED = 5
377
    ERROR_SHARING_VIOLATION = 32
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
378
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
379
    class _ctypes_FileLock(_OSLock):
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
380
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
381
        def _open(self, filename, access, share, cflags, pymode):
382
            self.filename = osutils.realpath(filename)
383
            handle = _CreateFile(filename, access, share, None, OPEN_ALWAYS,
7143.15.2 by Jelmer Vernooij
Run autopep8.
384
                                 FILE_ATTRIBUTE_NORMAL, 0)
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
385
            if handle in (INVALID_HANDLE_VALUE, 0):
386
                e = ctypes.WinError()
4459.3.2 by Martin
Fix issue with change of semantics of WindowsError.errno in Python 2.5
387
                if e.args[0] == ERROR_ACCESS_DENIED:
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
388
                    raise errors.LockFailed(filename, e)
4459.3.2 by Martin
Fix issue with change of semantics of WindowsError.errno in Python 2.5
389
                if e.args[0] == ERROR_SHARING_VIOLATION:
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
390
                    raise errors.LockContention(filename, e)
391
                raise e
392
            fd = msvcrt.open_osfhandle(handle, cflags)
393
            self.f = os.fdopen(fd, pymode)
394
            return self.f
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
395
396
        def unlock(self):
4404.1.1 by Martin
Correct use of GetLastError in ctypes windows locking code
397
            self._clear_f()
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
398
399
    class _ctypes_ReadLock(_ctypes_FileLock):
400
        def __init__(self, filename):
401
            super(_ctypes_ReadLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
402
            self._open(filename, GENERIC_READ, FILE_SHARE_READ, os.O_RDONLY,
7143.15.2 by Jelmer Vernooij
Run autopep8.
403
                       "rb")
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
404
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
405
        def temporary_write_lock(self):
406
            """Try to grab a write lock on the file.
407
408
            On platforms that support it, this will upgrade to a write lock
409
            without unlocking the file.
410
            Otherwise, this will release the read lock, and try to acquire a
411
            write lock.
412
413
            :return: A token which can be used to switch back to a read lock.
414
            """
415
            # I can't find a way to upgrade a read lock to a write lock without
416
            # unlocking first. So here, we do just that.
417
            self.unlock()
2353.4.7 by John Arbash Meinel
Change the temporary_write_lock api, so that it always returns a lock object,
418
            try:
419
                wlock = _ctypes_WriteLock(self.filename)
420
            except errors.LockError:
421
                return False, _ctypes_ReadLock(self.filename)
422
            return True, wlock
2353.3.11 by John Arbash Meinel
Code cleanup
423
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
424
    class _ctypes_WriteLock(_ctypes_FileLock):
425
        def __init__(self, filename):
426
            super(_ctypes_WriteLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
427
            self._open(filename, GENERIC_READ | GENERIC_WRITE, 0, os.O_RDWR,
7143.15.2 by Jelmer Vernooij
Run autopep8.
428
                       "rb+")
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
429
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
430
        def restore_read_lock(self):
431
            """Restore the original ReadLock."""
432
            # For win32 we had to completely let go of the original lock, so we
433
            # just unlock and create a new read lock.
434
            self.unlock()
2353.4.6 by John Arbash Meinel
ctypes locks should return ctypes locks.
435
            return _ctypes_ReadLock(self.filename)
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
436
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
437
    _lock_classes.append(('ctypes', _ctypes_WriteLock, _ctypes_ReadLock))
438
439
440
if len(_lock_classes) == 0:
2353.3.11 by John Arbash Meinel
Code cleanup
441
    raise NotImplementedError(
7341.1.1 by Martin
Remove win32 code using pywin32 library
442
        "We must have one of fcntl or ctypes available"
2353.3.11 by John Arbash Meinel
Code cleanup
443
        " to support OS locking."
444
        )
445
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
446
447
# We default to using the first available lock class.
448
_lock_type, WriteLock, ReadLock = _lock_classes[0]
449
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
450
451
class _RelockDebugMixin(object):
452
    """Mixin support for -Drelock flag.
453
454
    Add this as a base class then call self._note_lock with 'r' or 'w' when
455
    acquiring a read- or write-lock.  If this object was previously locked (and
456
    locked the same way), and -Drelock is set, then this will trace.note a
457
    message about it.
458
    """
6076.1.1 by Vincent Ladeuil
Add the missing config stacks and store
459
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
460
    _prev_lock = None
461
462
    def _note_lock(self, lock_type):
463
        if 'relock' in debug.debug_flags and self._prev_lock == lock_type:
464
            if lock_type == 'r':
465
                type_name = 'read'
466
            else:
467
                type_name = 'write'
6147.1.1 by Jonathan Riddell
use .format() instead of % for string formatting where there are multiple formats in one string to allow for translations
468
            trace.note(gettext('{0!r} was {1} locked again'), self, type_name)
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
469
        self._prev_lock = lock_type
470
7143.15.2 by Jelmer Vernooij
Run autopep8.
471
6538.1.11 by Aaron Bentley
Switch to much simpler implementation of restore_uncommitted.
472
@contextlib.contextmanager
473
def write_locked(lockable):
474
    lockable.lock_write()
475
    try:
476
        yield lockable
477
    finally:
478
        lockable.unlock()