~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lock.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-06-10 08:15:19 UTC
  • mfrom: (3489.1.2 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080610081519-95unlj6ayptlh2uv
(mbp) Bump version to 1.6b3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
18
"""Locking using OS file locks or file existence.
42
42
    osutils,
43
43
    trace,
44
44
    )
45
 
from bzrlib.hooks import HookPoint, Hooks
46
 
 
47
 
 
48
 
class LockHooks(Hooks):
49
 
 
50
 
    def __init__(self):
51
 
        Hooks.__init__(self)
52
 
        self.create_hook(HookPoint('lock_acquired',
53
 
            "Called with a bzrlib.lock.LockResult when a physical lock is "
54
 
            "acquired.", (1, 8), None))
55
 
        self.create_hook(HookPoint('lock_released',
56
 
            "Called with a bzrlib.lock.LockResult when a physical lock is "
57
 
            "released.", (1, 8), None))
58
 
 
59
 
 
60
 
class Lock(object):
61
 
    """Base class for locks.
62
 
 
63
 
    :cvar hooks: Hook dictionary for operations on locks.
64
 
    """
65
 
 
66
 
    hooks = LockHooks()
67
 
 
68
 
 
69
 
class LockResult(object):
70
 
    """Result of an operation on a lock; passed to a hook"""
71
 
 
72
 
    def __init__(self, lock_url, details=None):
73
 
        """Create a lock result for lock with optional details about the lock."""
74
 
        self.lock_url = lock_url
75
 
        self.details = details
76
 
 
77
 
    def __eq__(self, other):
78
 
        return self.lock_url == other.lock_url and self.details == other.details
79
 
 
80
 
 
81
 
try:
82
 
    import fcntl
83
 
    have_fcntl = True
84
 
except ImportError:
85
 
    have_fcntl = False
86
 
 
87
 
have_pywin32 = False
88
 
have_ctypes_win32 = False
89
 
if sys.platform == 'win32':
90
 
    import msvcrt
91
 
    try:
92
 
        import win32con, win32file, pywintypes, winerror
93
 
        have_pywin32 = True
94
 
    except ImportError:
95
 
        pass
96
 
 
97
 
    try:
98
 
        import ctypes
99
 
        have_ctypes_win32 = True
100
 
    except ImportError:
101
 
        pass
102
45
 
103
46
 
104
47
class _OSLock(object):
140
83
        raise NotImplementedError()
141
84
 
142
85
 
 
86
try:
 
87
    import fcntl
 
88
    have_fcntl = True
 
89
except ImportError:
 
90
    have_fcntl = False
 
91
try:
 
92
    import win32con, win32file, pywintypes, winerror, msvcrt
 
93
    have_pywin32 = True
 
94
except ImportError:
 
95
    have_pywin32 = False
 
96
try:
 
97
    import ctypes, msvcrt
 
98
    have_ctypes = True
 
99
except ImportError:
 
100
    have_ctypes = False
 
101
 
 
102
 
143
103
_lock_classes = []
144
104
 
145
105
 
183
143
                    self.unlock()
184
144
                # we should be more precise about whats a locking
185
145
                # error and whats a random-other error
186
 
                raise errors.LockContention(self.filename, e)
 
146
                raise errors.LockContention(e)
187
147
 
188
148
        def unlock(self):
189
149
            _fcntl_WriteLock._open_locks.remove(self.filename)
207
167
            except IOError, e:
208
168
                # we should be more precise about whats a locking
209
169
                # error and whats a random-other error
210
 
                raise errors.LockContention(self.filename, e)
 
170
                raise errors.LockContention(e)
211
171
 
212
172
        def unlock(self):
213
173
            count = _fcntl_ReadLock._open_locks[self.filename]
275
235
                fcntl.lockf(new_f, fcntl.LOCK_EX | fcntl.LOCK_NB)
276
236
            except IOError, e:
277
237
                # TODO: Raise a more specific error based on the type of error
278
 
                raise errors.LockContention(self.filename, e)
 
238
                raise errors.LockContention(e)
279
239
            _fcntl_WriteLock._open_locks.add(self.filename)
280
240
 
281
241
            self.f = new_f
320
280
                raise
321
281
            except Exception, e:
322
282
                self._clear_f()
323
 
                raise errors.LockContention(filename, e)
 
283
                raise errors.LockContention(e)
324
284
 
325
285
        def unlock(self):
326
286
            overlapped = pywintypes.OVERLAPPED()
328
288
                win32file.UnlockFileEx(self.hfile, 0, 0x7fff0000, overlapped)
329
289
                self._clear_f()
330
290
            except Exception, e:
331
 
                raise errors.LockContention(self.filename, e)
 
291
                raise errors.LockContention(e)
332
292
 
333
293
 
334
294
    class _w32c_ReadLock(_w32c_FileLock):
372
332
    _lock_classes.append(('pywin32', _w32c_WriteLock, _w32c_ReadLock))
373
333
 
374
334
 
375
 
if have_ctypes_win32:
 
335
if have_ctypes and sys.platform == 'win32':
376
336
    # These constants were copied from the win32con.py module.
377
337
    LOCKFILE_FAIL_IMMEDIATELY = 1
378
338
    LOCKFILE_EXCLUSIVE_LOCK = 2
437
397
                last_err = _GetLastError()
438
398
                if last_err in (ERROR_LOCK_VIOLATION,):
439
399
                    raise errors.LockContention(filename)
440
 
                raise errors.LockContention(filename,
441
 
                    'Unknown locking error: %s' % (last_err,))
 
400
                raise errors.LockContention('Unknown locking error: %s'
 
401
                                            % (last_err,))
442
402
 
443
403
        def unlock(self):
444
404
            overlapped = OVERLAPPED()
452
412
            if result == 0:
453
413
                self._clear_f()
454
414
                last_err = _GetLastError()
455
 
                raise errors.LockContention(self.filename,
456
 
                    'Unknown unlocking error: %s' % (last_err,))
 
415
                raise errors.LockContention('Unknown unlocking error: %s'
 
416
                                            % (last_err,))
457
417
 
458
418
 
459
419
    class _ctypes_ReadLock(_ctypes_FileLock):