27
27
It is not specified whether these locks are reentrant (i.e. can be
28
28
taken repeatedly by a single process) or whether they exclude
29
different threads in a single process. That reentrancy is provided by
29
different threads in a single process. That reentrancy is provided by
32
32
This defines two classes: ReadLock and WriteLock, which can be
88
88
except ImportError:
90
import win32con, win32file, pywintypes, winerror, msvcrt
97
raise NotImplementedError("please write a locking method "
98
"for platform %r" % sys.platform)
91
import win32con, win32file, pywintypes, winerror, msvcrt
167
WriteLock = _fcntl_WriteLock
168
ReadLock = _fcntl_ReadLock
171
_lock_classes.append(('fcntl', _fcntl_WriteLock, _fcntl_ReadLock))
171
174
LOCK_SH = 0 # the default
172
175
LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
173
176
LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
212
215
super(_w32c_WriteLock, self).__init__()
213
216
self._lock(filename, 'rb+', LOCK_EX + LOCK_NB)
215
WriteLock = _w32c_WriteLock
216
ReadLock = _w32c_ReadLock
218
assert have_ctypes, "We should have ctypes installed"
218
_lock_classes.append(('pywin32', _w32c_WriteLock, _w32c_ReadLock))
219
221
# These constants were copied from the win32con.py module.
220
222
LOCKFILE_FAIL_IMMEDIATELY = 1
221
223
LOCKFILE_EXCLUSIVE_LOCK = 2
311
313
super(_ctypes_WriteLock, self).__init__()
312
314
self._lock(filename, 'rb+', LOCK_EX + LOCK_NB)
314
WriteLock = _ctypes_WriteLock
315
ReadLock = _ctypes_ReadLock
316
_lock_classes.append(('ctypes', _ctypes_WriteLock, _ctypes_ReadLock))
319
if len(_lock_classes) == 0:
320
raise NotImplementedError("We only have support for"
321
" fcntl, pywin32 or ctypes locking."
322
" If your platform (windows) does not"
323
" support fcntl locks, you must have"
324
" either pywin32 or ctypes installed.")
326
# We default to using the first available lock class.
327
_lock_type, WriteLock, ReadLock = _lock_classes[0]
330
class LockTreeTestProviderAdapter(object):
331
"""A tool to generate a suite testing multiple lock formats at once.
333
This is done by copying the test once for each lock and injecting the
334
read_lock and write_lock classes.
335
They are also given a new test id.
338
def __init__(self, lock_classes):
339
self._lock_classes = lock_classes
341
def _clone_test(self, test, write_lock, read_lock, variation):
342
"""Clone test for adaption."""
343
new_test = deepcopy(test)
344
new_test.write_lock = write_lock
345
new_test.read_lock = read_lock
346
def make_new_test_id():
347
new_id = "%s(%s)" % (test.id(), variation)
348
return lambda: new_id
349
new_test.id = make_new_test_id()
352
def adapt(self, test):
353
from bzrlib.tests import TestSuite
355
for name, write_lock, read_lock in self._lock_classes:
356
new_test = self._clone_test(test, write_lock, read_lock, name)
357
result.addTest(new_test)