/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
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
36
from __future__ import absolute_import
37
6538.1.11 by Aaron Bentley
Switch to much simpler implementation of restore_uncommitted.
38
import contextlib
1185.65.29 by Robert Collins
Implement final review suggestions.
39
import errno
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
40
import os
2353.3.12 by John Arbash Meinel
Don't create the alternative lock types unless we are on windows.
41
import sys
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
42
import warnings
577 by Martin Pool
- merge portable lock module from John
43
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
44
from . import (
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
45
    debug,
2353.3.11 by John Arbash Meinel
Code cleanup
46
    errors,
47
    osutils,
48
    trace,
49
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
50
from .hooks import Hooks
51
from .i18n import gettext
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
52
7143.15.2 by Jelmer Vernooij
Run autopep8.
53
3724.1.1 by Martin Pool
Move Lock hooks onto a base Lock class and make them more consistent with other lock classes
54
class LockHooks(Hooks):
55
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
56
    def __init__(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
57
        Hooks.__init__(self, "breezy.lock", "Lock.hooks")
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
58
        self.add_hook(
59
            'lock_acquired',
60
            "Called with a breezy.lock.LockResult when a physical lock is "
61
            "acquired.", (1, 8))
62
        self.add_hook(
63
            'lock_released',
64
            "Called with a breezy.lock.LockResult when a physical lock is "
65
            "released.", (1, 8))
66
        self.add_hook(
67
            'lock_broken',
68
            "Called with a breezy.lock.LockResult when a physical lock is "
69
            "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
70
71
72
class Lock(object):
73
    """Base class for locks.
74
75
    :cvar hooks: Hook dictionary for operations on locks.
76
    """
77
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
78
    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
79
80
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
81
class LockResult(object):
3331.3.5 by Martin Pool
Move physical lock hooks onto new PhysicalLock class variable
82
    """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
83
3331.3.2 by Robert Collins
Polish on lock hooks to be easier to use.
84
    def __init__(self, lock_url, details=None):
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
85
        """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.
86
        self.lock_url = lock_url
3331.3.1 by Robert Collins
* ``LockDir`` lock acquisition and release now trigger hooks allowing
87
        self.details = details
88
89
    def __eq__(self, other):
3331.3.2 by Robert Collins
Polish on lock hooks to be easier to use.
90
        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
91
4327.1.1 by Vincent Ladeuil
Start addressing test failing when run with -Dlock.
92
    def __repr__(self):
4634.146.9 by Danny van Heumen
Changed representation of LockResult: separate path and nonce with a comma.
93
        return '%s(%s, %s)' % (self.__class__.__name__,
7143.15.2 by Jelmer Vernooij
Run autopep8.
94
                               self.lock_url, self.details)
4327.1.1 by Vincent Ladeuil
Start addressing test failing when run with -Dlock.
95
577 by Martin Pool
- merge portable lock module from John
96
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
97
class LogicalLockResult(object):
98
    """The result of a lock_read/lock_write/lock_tree_write call on lockables.
99
100
    :ivar unlock: A callable which will unlock the lock.
101
    """
102
6754.8.4 by Jelmer Vernooij
Use new context stuff.
103
    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.
104
        self.unlock = unlock
6754.8.4 by Jelmer Vernooij
Use new context stuff.
105
        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.
106
107
    def __repr__(self):
108
        return "LogicalLockResult(%s)" % (self.unlock)
109
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
110
    def __enter__(self):
6754.8.9 by Jelmer Vernooij
Fix more tests.
111
        return self
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
112
113
    def __exit__(self, exc_type, exc_val, exc_tb):
6754.8.12 by Jelmer Vernooij
FIx remaining tests.
114
        # If there was an error raised, prefer the original one
115
        try:
116
            self.unlock()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
117
        except BaseException:
6754.8.12 by Jelmer Vernooij
FIx remaining tests.
118
            if exc_type is None:
119
                raise
6754.8.1 by Jelmer Vernooij
Add context manager on LogicalLockResult.
120
        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.
121
122
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
123
def cant_unlock_not_held(locked_object):
124
    """An attempt to unlock failed because the object was not locked.
125
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
126
    This provides a policy point from which we can generate either a warning or
127
    an exception.
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
128
    """
129
    # 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
130
    # 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
131
    # here.  You can use -Werror to make it fatal.  It should possibly also
132
    # raise LockNotHeld.
4509.3.27 by Martin Pool
Change debug flag to -Dunlock and document it
133
    if 'unlock' in debug.debug_flags:
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
134
        warnings.warn("%r is already unlocked" % (locked_object,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
135
                      stacklevel=3)
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
136
    else:
137
        raise errors.LockNotHeld(locked_object)
138
139
3224.5.32 by Andrew Bennetts
Tidy conditional imports in bzrlib/lock.py as suggested by John's review.
140
try:
141
    import fcntl
142
    have_fcntl = True
143
except ImportError:
144
    have_fcntl = False
145
146
have_pywin32 = False
147
have_ctypes_win32 = False
148
if sys.platform == 'win32':
149
    import msvcrt
150
    try:
7143.15.2 by Jelmer Vernooij
Run autopep8.
151
        import win32file
152
        import pywintypes
153
        import winerror
3224.5.32 by Andrew Bennetts
Tidy conditional imports in bzrlib/lock.py as suggested by John's review.
154
        have_pywin32 = True
155
    except ImportError:
156
        pass
157
158
    try:
159
        import ctypes
160
        have_ctypes_win32 = True
161
    except ImportError:
162
        pass
163
164
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
165
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.
166
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
167
    def __init__(self):
168
        self.f = None
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
169
        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.
170
615 by Martin Pool
Major rework of locking code:
171
    def _open(self, filename, filemode):
2353.3.11 by John Arbash Meinel
Code cleanup
172
        self.filename = osutils.realpath(filename)
656 by Martin Pool
- create branch lock files if they don't exist
173
        try:
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
174
            self.f = open(self.filename, filemode)
656 by Martin Pool
- create branch lock files if they don't exist
175
            return self.f
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
176
        except IOError as e:
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
177
            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).
178
                raise errors.LockFailed(self.filename, str(e))
656 by Martin Pool
- create branch lock files if they don't exist
179
            if e.errno != errno.ENOENT:
180
                raise
181
182
            # maybe this is an old branch (before may 2005)
2353.3.11 by John Arbash Meinel
Code cleanup
183
            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
184
2353.3.10 by John Arbash Meinel
Cleanup errors, and change ReadOnlyLockError to pass around more details.
185
            self.f = open(self.filename, 'wb+')
656 by Martin Pool
- create branch lock files if they don't exist
186
            return self.f
187
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
188
    def _clear_f(self):
189
        """Clear the self.f attribute cleanly."""
190
        if self.f:
191
            self.f.close()
192
            self.f = None
193
615 by Martin Pool
Major rework of locking code:
194
    def unlock(self):
195
        raise NotImplementedError()
196
197
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
198
_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.
199
200
201
if have_fcntl:
615 by Martin Pool
Major rework of locking code:
202
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
203
    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.
204
205
        def _unlock(self):
1185.9.2 by Harald Meland
Use fcntl.lockf() rather than fcntl.flock() to support NFS file systems.
206
            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.
207
            self._clear_f()
208
615 by Martin Pool
Major rework of locking code:
209
    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.
210
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
211
        _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.
212
615 by Martin Pool
Major rework of locking code:
213
        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.
214
            super(_fcntl_WriteLock, self).__init__()
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
215
            # Check we can grab a lock before we actually open the file.
216
            self.filename = osutils.realpath(filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
217
            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.
218
                self._clear_f()
219
                raise errors.LockContention(self.filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
220
            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.
221
                if 'strict_locks' in debug.debug_flags:
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
222
                    self._clear_f()
223
                    raise errors.LockContention(self.filename)
224
                else:
225
                    trace.mutter('Write lock taken w/ an open read lock on: %s'
226
                                 % (self.filename,))
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
227
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
228
            self._open(self.filename, 'rb+')
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
229
            # reserve a slot for this lock - even if the lockf call fails,
5009.1.1 by Vincent Ladeuil
(trivial) Fix typos
230
            # at this point unlock() will be called, because self.f is set.
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
231
            # 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.
232
            _fcntl_WriteLock._open_locks.add(self.filename)
615 by Martin Pool
Major rework of locking code:
233
            try:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
234
                # LOCK_NB will cause IOError to be raised if we can't grab a
235
                # lock right away.
236
                fcntl.lockf(self.f, fcntl.LOCK_EX | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
237
            except IOError as e:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
238
                if e.errno in (errno.EAGAIN, errno.EACCES):
239
                    # We couldn't grab the lock
240
                    self.unlock()
1185.65.29 by Robert Collins
Implement final review suggestions.
241
                # we should be more precise about whats a locking
242
                # error and whats a random-other error
4100.1.4 by Martin Pool
LockContention on OS locks now includes the filename
243
                raise errors.LockContention(self.filename, e)
615 by Martin Pool
Major rework of locking code:
244
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
245
        def unlock(self):
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
246
            _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.
247
            self._unlock()
248
615 by Martin Pool
Major rework of locking code:
249
    class _fcntl_ReadLock(_fcntl_FileLock):
1185.65.29 by Robert Collins
Implement final review suggestions.
250
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
251
        _open_locks = {}
2353.3.3 by John Arbash Meinel
Define an explicit error when trying to grab a write lock on a readonly file.
252
2353.4.11 by John Arbash Meinel
Remove the unused _ignore_write_lock parameter.
253
        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.
254
            super(_fcntl_ReadLock, self).__init__()
2353.4.2 by John Arbash Meinel
[merge] LockCleanup changes.
255
            self.filename = osutils.realpath(filename)
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
256
            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.
257
                if 'strict_locks' in debug.debug_flags:
4523.4.14 by John Arbash Meinel
Fix the direct lock tests.
258
                    # We raise before calling _open so we don't need to
259
                    # _clear_f
4523.4.9 by John Arbash Meinel
Change the flags around a bit.
260
                    raise errors.LockContention(self.filename)
261
                else:
262
                    trace.mutter('Read lock taken w/ an open write lock on: %s'
263
                                 % (self.filename,))
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
264
            _fcntl_ReadLock._open_locks.setdefault(self.filename, 0)
265
            _fcntl_ReadLock._open_locks[self.filename] += 1
1185.65.29 by Robert Collins
Implement final review suggestions.
266
            self._open(filename, 'rb')
615 by Martin Pool
Major rework of locking code:
267
            try:
2255.10.2 by John Arbash Meinel
Update to dirstate locking.
268
                # LOCK_NB will cause IOError to be raised if we can't grab a
269
                # lock right away.
270
                fcntl.lockf(self.f, fcntl.LOCK_SH | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
271
            except IOError as e:
1185.65.29 by Robert Collins
Implement final review suggestions.
272
                # we should be more precise about whats a locking
273
                # error and whats a random-other error
4100.1.4 by Martin Pool
LockContention on OS locks now includes the filename
274
                raise errors.LockContention(self.filename, e)
615 by Martin Pool
Major rework of locking code:
275
1852.4.3 by Robert Collins
Alter working tree lock and unlock tests to test via the interface rather than via unpublished internals.
276
        def unlock(self):
2353.4.1 by John Arbash Meinel
(broken) Change fcntl locks to be properly exclusive within the same process.
277
            count = _fcntl_ReadLock._open_locks[self.filename]
278
            if count == 1:
279
                del _fcntl_ReadLock._open_locks[self.filename]
280
            else:
281
                _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.
282
            self._unlock()
283
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
284
        def temporary_write_lock(self):
285
            """Try to grab a write lock on the file.
286
287
            On platforms that support it, this will upgrade to a write lock
288
            without unlocking the file.
289
            Otherwise, this will release the read lock, and try to acquire a
290
            write lock.
291
292
            :return: A token which can be used to switch back to a read lock.
293
            """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
294
            if self.filename in _fcntl_WriteLock._open_locks:
295
                raise AssertionError('file already locked: %r'
7143.15.2 by Jelmer Vernooij
Run autopep8.
296
                                     % (self.filename,))
2353.4.7 by John Arbash Meinel
Change the temporary_write_lock api, so that it always returns a lock object,
297
            try:
298
                wlock = _fcntl_TemporaryWriteLock(self)
299
            except errors.LockError:
300
                # We didn't unlock, so we can just return 'self'
301
                return False, self
302
            return True, wlock
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
303
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
304
    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.
305
        """A token used when grabbing a temporary_write_lock.
306
307
        Call restore_read_lock() when you are done with the write lock.
308
        """
309
310
        def __init__(self, read_lock):
311
            super(_fcntl_TemporaryWriteLock, self).__init__()
312
            self._read_lock = read_lock
313
            self.filename = read_lock.filename
314
315
            count = _fcntl_ReadLock._open_locks[self.filename]
316
            if count > 1:
317
                # Something else also has a read-lock, so we cannot grab a
318
                # write lock.
319
                raise errors.LockContention(self.filename)
320
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
321
            if self.filename in _fcntl_WriteLock._open_locks:
322
                raise AssertionError('file already locked: %r'
7143.15.2 by Jelmer Vernooij
Run autopep8.
323
                                     % (self.filename,))
2353.4.3 by John Arbash Meinel
Implement a 'ReadLock.temporary_write_lock()' to upgrade to a write-lock in-process.
324
325
            # See if we can open the file for writing. Another process might
326
            # have a read lock. We don't use self._open() because we don't want
327
            # to create the file if it exists. That would have already been
328
            # done by _fcntl_ReadLock
329
            try:
330
                new_f = open(self.filename, 'rb+')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
331
            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.
332
                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).
333
                    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.
334
                raise
335
            try:
336
                # LOCK_NB will cause IOError to be raised if we can't grab a
337
                # lock right away.
2379.3.1 by John Arbash Meinel
Cherry-pick the 2 locking fixes from the 0.15 branch.
338
                fcntl.lockf(new_f, fcntl.LOCK_EX | fcntl.LOCK_NB)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
339
            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.
340
                # 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
341
                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.
342
            _fcntl_WriteLock._open_locks.add(self.filename)
343
344
            self.f = new_f
345
346
        def restore_read_lock(self):
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
347
            """Restore the original ReadLock."""
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
348
            # For fcntl, since we never released the read lock, just release
349
            # 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.
350
            fcntl.lockf(self.f, fcntl.LOCK_UN)
351
            self._clear_f()
352
            _fcntl_WriteLock._open_locks.remove(self.filename)
353
            # Avoid reference cycles
354
            read_lock = self._read_lock
355
            self._read_lock = None
356
            return read_lock
357
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
358
    _lock_classes.append(('fcntl', _fcntl_WriteLock, _fcntl_ReadLock))
577 by Martin Pool
- merge portable lock module from John
359
2353.3.11 by John Arbash Meinel
Code cleanup
360
2353.3.12 by John Arbash Meinel
Don't create the alternative lock types unless we are on windows.
361
if have_pywin32 and sys.platform == 'win32':
6658.6.1 by Martin
Remove winver, win98 support code, and deprecated code
362
    win32file_CreateFile = win32file.CreateFileW
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
363
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
364
    class _w32c_FileLock(_OSLock):
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
365
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
366
        def _open(self, filename, access, share, cflags, pymode):
367
            self.filename = osutils.realpath(filename)
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
368
            try:
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
369
                self._handle = win32file_CreateFile(
370
                    filename, access, share, None, win32file.OPEN_ALWAYS,
371
                    win32file.FILE_ATTRIBUTE_NORMAL, None)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
372
            except pywintypes.error as e:
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
373
                if e.args[0] == winerror.ERROR_ACCESS_DENIED:
374
                    raise errors.LockFailed(filename, e)
375
                if e.args[0] == winerror.ERROR_SHARING_VIOLATION:
376
                    raise errors.LockContention(filename, e)
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
377
                raise
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
378
            fd = win32file._open_osfhandle(self._handle, cflags)
379
            self.f = os.fdopen(fd, pymode)
380
            return self.f
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
381
382
        def unlock(self):
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
383
            self._clear_f()
384
            self._handle = None
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
385
386
    class _w32c_ReadLock(_w32c_FileLock):
387
        def __init__(self, filename):
388
            super(_w32c_ReadLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
389
            self._open(filename, win32file.GENERIC_READ,
7143.15.2 by Jelmer Vernooij
Run autopep8.
390
                       win32file.FILE_SHARE_READ, os.O_RDONLY, "rb")
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
391
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
392
        def temporary_write_lock(self):
393
            """Try to grab a write lock on the file.
394
395
            On platforms that support it, this will upgrade to a write lock
396
            without unlocking the file.
397
            Otherwise, this will release the read lock, and try to acquire a
398
            write lock.
399
400
            :return: A token which can be used to switch back to a read lock.
401
            """
402
            # I can't find a way to upgrade a read lock to a write lock without
403
            # unlocking first. So here, we do just that.
404
            self.unlock()
2353.4.7 by John Arbash Meinel
Change the temporary_write_lock api, so that it always returns a lock object,
405
            try:
406
                wlock = _w32c_WriteLock(self.filename)
407
            except errors.LockError:
408
                return False, _w32c_ReadLock(self.filename)
409
            return True, wlock
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
410
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
411
    class _w32c_WriteLock(_w32c_FileLock):
412
        def __init__(self, filename):
413
            super(_w32c_WriteLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
414
            self._open(filename,
7143.15.2 by Jelmer Vernooij
Run autopep8.
415
                       win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0,
416
                       os.O_RDWR, "rb+")
2353.3.4 by John Arbash Meinel
Clean up the lock.py code to use less indenting, and conform to better coding practise.
417
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
418
        def restore_read_lock(self):
419
            """Restore the original ReadLock."""
420
            # For win32 we had to completely let go of the original lock, so we
421
            # just unlock and create a new read lock.
422
            self.unlock()
423
            return _w32c_ReadLock(self.filename)
424
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
425
    _lock_classes.append(('pywin32', _w32c_WriteLock, _w32c_ReadLock))
426
2353.3.11 by John Arbash Meinel
Code cleanup
427
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.
428
if have_ctypes_win32:
7143.11.1 by Jelmer Vernooij
Remove some unused imports.
429
    from ctypes.wintypes import DWORD, LPWSTR
7143.15.2 by Jelmer Vernooij
Run autopep8.
430
    LPSECURITY_ATTRIBUTES = ctypes.c_void_p  # used as NULL no need to declare
431
    HANDLE = ctypes.c_int  # rather than unsigned as in ctypes.wintypes
6658.6.1 by Martin
Remove winver, win98 support code, and deprecated code
432
    _function_name = "CreateFileW"
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
433
434
    # CreateFile <http://msdn.microsoft.com/en-us/library/aa363858.aspx>
435
    _CreateFile = ctypes.WINFUNCTYPE(
7143.15.2 by Jelmer Vernooij
Run autopep8.
436
        HANDLE,                # return value
437
        LPWSTR,                # lpFileName
438
        DWORD,                 # dwDesiredAccess
439
        DWORD,                 # dwShareMode
440
        LPSECURITY_ATTRIBUTES,  # lpSecurityAttributes
441
        DWORD,                 # dwCreationDisposition
442
        DWORD,                 # dwFlagsAndAttributes
443
        HANDLE                 # hTemplateFile
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
444
        )((_function_name, ctypes.windll.kernel32))
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
445
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
446
    INVALID_HANDLE_VALUE = -1
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
447
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
448
    GENERIC_READ = 0x80000000
449
    GENERIC_WRITE = 0x40000000
450
    FILE_SHARE_READ = 1
451
    OPEN_ALWAYS = 4
452
    FILE_ATTRIBUTE_NORMAL = 128
4523.4.1 by John Arbash Meinel
Start adding some direct testing for read and write locks.
453
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
454
    ERROR_ACCESS_DENIED = 5
455
    ERROR_SHARING_VIOLATION = 32
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
456
2555.3.2 by Martin Pool
rename _base_Lock to _OSLock
457
    class _ctypes_FileLock(_OSLock):
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
458
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
459
        def _open(self, filename, access, share, cflags, pymode):
460
            self.filename = osutils.realpath(filename)
461
            handle = _CreateFile(filename, access, share, None, OPEN_ALWAYS,
7143.15.2 by Jelmer Vernooij
Run autopep8.
462
                                 FILE_ATTRIBUTE_NORMAL, 0)
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
463
            if handle in (INVALID_HANDLE_VALUE, 0):
464
                e = ctypes.WinError()
4459.3.2 by Martin
Fix issue with change of semantics of WindowsError.errno in Python 2.5
465
                if e.args[0] == ERROR_ACCESS_DENIED:
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
466
                    raise errors.LockFailed(filename, e)
4459.3.2 by Martin
Fix issue with change of semantics of WindowsError.errno in Python 2.5
467
                if e.args[0] == ERROR_SHARING_VIOLATION:
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
468
                    raise errors.LockContention(filename, e)
469
                raise e
470
            fd = msvcrt.open_osfhandle(handle, cflags)
471
            self.f = os.fdopen(fd, pymode)
472
            return self.f
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
473
474
        def unlock(self):
4404.1.1 by Martin
Correct use of GetLastError in ctypes windows locking code
475
            self._clear_f()
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
476
477
    class _ctypes_ReadLock(_ctypes_FileLock):
478
        def __init__(self, filename):
479
            super(_ctypes_ReadLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
480
            self._open(filename, GENERIC_READ, FILE_SHARE_READ, os.O_RDONLY,
7143.15.2 by Jelmer Vernooij
Run autopep8.
481
                       "rb")
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
482
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
483
        def temporary_write_lock(self):
484
            """Try to grab a write lock on the file.
485
486
            On platforms that support it, this will upgrade to a write lock
487
            without unlocking the file.
488
            Otherwise, this will release the read lock, and try to acquire a
489
            write lock.
490
491
            :return: A token which can be used to switch back to a read lock.
492
            """
493
            # I can't find a way to upgrade a read lock to a write lock without
494
            # unlocking first. So here, we do just that.
495
            self.unlock()
2353.4.7 by John Arbash Meinel
Change the temporary_write_lock api, so that it always returns a lock object,
496
            try:
497
                wlock = _ctypes_WriteLock(self.filename)
498
            except errors.LockError:
499
                return False, _ctypes_ReadLock(self.filename)
500
            return True, wlock
2353.3.11 by John Arbash Meinel
Code cleanup
501
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
502
    class _ctypes_WriteLock(_ctypes_FileLock):
503
        def __init__(self, filename):
504
            super(_ctypes_WriteLock, self).__init__()
4459.3.1 by Martin
Implement bzrlib.lock with CreateFile rather than LockFileEx on win32
505
            self._open(filename, GENERIC_READ | GENERIC_WRITE, 0, os.O_RDWR,
7143.15.2 by Jelmer Vernooij
Run autopep8.
506
                       "rb+")
2353.3.5 by John Arbash Meinel
Fall back on ctypes to get LockFileEx, because msvcrt.locking()
507
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
508
        def restore_read_lock(self):
509
            """Restore the original ReadLock."""
510
            # For win32 we had to completely let go of the original lock, so we
511
            # just unlock and create a new read lock.
512
            self.unlock()
2353.4.6 by John Arbash Meinel
ctypes locks should return ctypes locks.
513
            return _ctypes_ReadLock(self.filename)
2353.4.4 by John Arbash Meinel
Implement temporary_write_lock, and restore_read_lock for win32 locks.
514
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
515
    _lock_classes.append(('ctypes', _ctypes_WriteLock, _ctypes_ReadLock))
516
517
518
if len(_lock_classes) == 0:
2353.3.11 by John Arbash Meinel
Code cleanup
519
    raise NotImplementedError(
520
        "We must have one of fcntl, pywin32, or ctypes available"
521
        " to support OS locking."
522
        )
523
2353.3.9 by John Arbash Meinel
Update the lock code and test code so that if more than one
524
525
# We default to using the first available lock class.
526
_lock_type, WriteLock, ReadLock = _lock_classes[0]
527
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
528
529
class _RelockDebugMixin(object):
530
    """Mixin support for -Drelock flag.
531
532
    Add this as a base class then call self._note_lock with 'r' or 'w' when
533
    acquiring a read- or write-lock.  If this object was previously locked (and
534
    locked the same way), and -Drelock is set, then this will trace.note a
535
    message about it.
536
    """
6076.1.1 by Vincent Ladeuil
Add the missing config stacks and store
537
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
538
    _prev_lock = None
539
540
    def _note_lock(self, lock_type):
541
        if 'relock' in debug.debug_flags and self._prev_lock == lock_type:
542
            if lock_type == 'r':
543
                type_name = 'read'
544
            else:
545
                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
546
            trace.note(gettext('{0!r} was {1} locked again'), self, type_name)
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
547
        self._prev_lock = lock_type
548
7143.15.2 by Jelmer Vernooij
Run autopep8.
549
6538.1.11 by Aaron Bentley
Switch to much simpler implementation of restore_uncommitted.
550
@contextlib.contextmanager
551
def write_locked(lockable):
552
    lockable.lock_write()
553
    try:
554
        yield lockable
555
    finally:
556
        lockable.unlock()