~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: 2007-03-07 10:45:44 UTC
  • mfrom: (2321.1.2 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20070307104544-59e3e6358e4bdb29
(robertc) Merge dirstate and subtrees. (Robert Collins, Martin Pool, Aaaron Bentley, John A Meinel, James Westby)

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
import os
39
39
import sys
40
40
 
41
 
from bzrlib.errors import LockError
 
41
from bzrlib.errors import LockError, LockContention
42
42
from bzrlib.osutils import realpath
43
43
from bzrlib.trace import mutter
44
44
 
87
87
        def _clear_f(self):
88
88
            """Clear the self.f attribute cleanly."""
89
89
            self.f.close()
90
 
            del self.f 
 
90
            del self.f
91
91
 
92
92
 
93
93
    class _fcntl_WriteLock(_fcntl_FileLock):
96
96
 
97
97
        def __init__(self, filename):
98
98
            # standard IO errors get exposed directly.
99
 
            self._open(filename, 'wb')
 
99
            self._open(filename, 'rb+')
 
100
            self.filename = realpath(filename)
 
101
            if self.filename in self.open_locks:
 
102
                self._clear_f()
 
103
                raise LockContention("Lock already held.")
 
104
            # reserve a slot for this lock - even if the lockf call fails,
 
105
            # at thisi point unlock() will be called, because self.f is set.
 
106
            # TODO: make this fully threadsafe, if we decide we care.
 
107
            self.open_locks[self.filename] = self.filename
100
108
            try:
101
 
                self.filename = realpath(filename)
102
 
                if self.filename in self.open_locks:
103
 
                    self._clear_f() 
104
 
                    raise LockError("Lock already held.")
105
 
                # reserve a slot for this lock - even if the lockf call fails, 
106
 
                # at thisi point unlock() will be called, because self.f is set.
107
 
                # TODO: make this fully threadsafe, if we decide we care.
108
 
                self.open_locks[self.filename] = self.filename
109
 
                fcntl.lockf(self.f, fcntl.LOCK_EX)
 
109
                # LOCK_NB will cause IOError to be raised if we can't grab a
 
110
                # lock right away.
 
111
                fcntl.lockf(self.f, fcntl.LOCK_EX | fcntl.LOCK_NB)
110
112
            except IOError, e:
 
113
                if e.errno in (errno.EAGAIN, errno.EACCES):
 
114
                    # We couldn't grab the lock
 
115
                    self.unlock()
111
116
                # we should be more precise about whats a locking
112
117
                # error and whats a random-other error
113
118
                raise LockError(e)
123
128
            # standard IO errors get exposed directly.
124
129
            self._open(filename, 'rb')
125
130
            try:
126
 
                fcntl.lockf(self.f, fcntl.LOCK_SH)
 
131
                # LOCK_NB will cause IOError to be raised if we can't grab a
 
132
                # lock right away.
 
133
                fcntl.lockf(self.f, fcntl.LOCK_SH | fcntl.LOCK_NB)
127
134
            except IOError, e:
128
135
                # we should be more precise about whats a locking
129
136
                # error and whats a random-other error
176
183
 
177
184
        class _w32c_WriteLock(_w32c_FileLock):
178
185
            def __init__(self, filename):
179
 
                _w32c_FileLock._lock(self, filename, 'wb',
 
186
                _w32c_FileLock._lock(self, filename, 'rb+',
180
187
                                     LOCK_EX + LOCK_NB)
181
188
 
182
189
 
198
205
                LOCK_SH = 1
199
206
                LOCK_EX = 2
200
207
                LOCK_NB = 4
 
208
 
201
209
                def unlock(self):
202
210
                    _msvc_unlock(self.f)
203
211
                    self.f.close()
206
214
 
207
215
            class _msvc_ReadLock(_msvc_FileLock):
208
216
                def __init__(self, filename):
209
 
                    _msvc_lock(self._open(filename, 'rb'), self.LOCK_SH)
 
217
                    _msvc_lock(self._open(filename, 'rb'),
 
218
                               self.LOCK_SH | self.LOCK_NB)
210
219
 
211
220
 
212
221
            class _msvc_WriteLock(_msvc_FileLock):
213
222
                def __init__(self, filename):
214
 
                    _msvc_lock(self._open(filename, 'wb'), self.LOCK_EX)
 
223
                    _msvc_lock(self._open(filename, 'rb+'),
 
224
                               self.LOCK_EX | self.LOCK_NB)
215
225
 
216
226
 
217
227
            def _msvc_lock(f, flags):