~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lock.py

  • Committer: John Arbash Meinel
  • Date: 2009-07-08 14:37:25 UTC
  • mfrom: (4516 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4517.
  • Revision ID: john@arbash-meinel.com-20090708143725-sc9sjy3mz4cxwxzz
Merge bzr.dev 4516

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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
37
37
import errno
38
38
import os
39
39
import sys
40
 
import warnings
41
40
 
42
41
from bzrlib import (
43
 
    debug,
44
42
    errors,
45
43
    osutils,
46
44
    trace,
88
86
                             self.lock_url, self.details)
89
87
 
90
88
 
91
 
def cant_unlock_not_held(locked_object):
92
 
    """An attempt to unlock failed because the object was not locked.
93
 
 
94
 
    This provides a policy point from which we can generate either a warning 
95
 
    or an exception.
96
 
    """
97
 
    # This is typically masking some other error and called from a finally
98
 
    # block, so it's useful to have the option not to generate a new error
99
 
    # here.  You can use -Werror to make it fatal.  It should possibly also
100
 
    # raise LockNotHeld.
101
 
    if 'unlock' in debug.debug_flags:
102
 
        warnings.warn("%r is already unlocked" % (locked_object,),
103
 
            stacklevel=3)
104
 
    else:
105
 
        raise errors.LockNotHeld(locked_object)
106
 
 
107
 
 
108
89
try:
109
90
    import fcntl
110
91
    have_fcntl = True
190
171
            if self.filename in _fcntl_WriteLock._open_locks:
191
172
                self._clear_f()
192
173
                raise errors.LockContention(self.filename)
193
 
            if self.filename in _fcntl_ReadLock._open_locks:
194
 
                if 'strict_locks' in debug.debug_flags:
195
 
                    self._clear_f()
196
 
                    raise errors.LockContention(self.filename)
197
 
                else:
198
 
                    trace.mutter('Write lock taken w/ an open read lock on: %s'
199
 
                                 % (self.filename,))
200
174
 
201
175
            self._open(self.filename, 'rb+')
202
176
            # reserve a slot for this lock - even if the lockf call fails,
203
 
            # at this point unlock() will be called, because self.f is set.
 
177
            # at thisi point unlock() will be called, because self.f is set.
204
178
            # TODO: make this fully threadsafe, if we decide we care.
205
179
            _fcntl_WriteLock._open_locks.add(self.filename)
206
180
            try:
227
201
        def __init__(self, filename):
228
202
            super(_fcntl_ReadLock, self).__init__()
229
203
            self.filename = osutils.realpath(filename)
230
 
            if self.filename in _fcntl_WriteLock._open_locks:
231
 
                if 'strict_locks' in debug.debug_flags:
232
 
                    # We raise before calling _open so we don't need to
233
 
                    # _clear_f
234
 
                    raise errors.LockContention(self.filename)
235
 
                else:
236
 
                    trace.mutter('Read lock taken w/ an open write lock on: %s'
237
 
                                 % (self.filename,))
238
204
            _fcntl_ReadLock._open_locks.setdefault(self.filename, 0)
239
205
            _fcntl_ReadLock._open_locks[self.filename] += 1
240
206
            self._open(filename, 'rb')
433
399
            DWORD,                 # dwFlagsAndAttributes
434
400
            HANDLE                 # hTemplateFile
435
401
        )((_function_name, ctypes.windll.kernel32))
436
 
 
 
402
    
437
403
    INVALID_HANDLE_VALUE = -1
438
 
 
 
404
    
439
405
    GENERIC_READ = 0x80000000
440
406
    GENERIC_WRITE = 0x40000000
441
407
    FILE_SHARE_READ = 1
442
408
    OPEN_ALWAYS = 4
443
409
    FILE_ATTRIBUTE_NORMAL = 128
444
 
 
 
410
    
445
411
    ERROR_ACCESS_DENIED = 5
446
412
    ERROR_SHARING_VIOLATION = 32
447
413
 
518
484
# We default to using the first available lock class.
519
485
_lock_type, WriteLock, ReadLock = _lock_classes[0]
520
486
 
521
 
 
522
 
class _RelockDebugMixin(object):
523
 
    """Mixin support for -Drelock flag.
524
 
 
525
 
    Add this as a base class then call self._note_lock with 'r' or 'w' when
526
 
    acquiring a read- or write-lock.  If this object was previously locked (and
527
 
    locked the same way), and -Drelock is set, then this will trace.note a
528
 
    message about it.
529
 
    """
530
 
    
531
 
    _prev_lock = None
532
 
 
533
 
    def _note_lock(self, lock_type):
534
 
        if 'relock' in debug.debug_flags and self._prev_lock == lock_type:
535
 
            if lock_type == 'r':
536
 
                type_name = 'read'
537
 
            else:
538
 
                type_name = 'write'
539
 
            trace.note('%r was %s locked again', self, type_name)
540
 
        self._prev_lock = lock_type
541