~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lock.py

merge dirstate

Show diffs side-by-side

added added

removed removed

Lines of Context:
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):
97
97
        def __init__(self, filename):
98
98
            # standard IO errors get exposed directly.
99
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 LockContention("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
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, 'rb+'), 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):