29
29
Eventually we may need to use some kind of lock representation that
30
30
will work on a dumb filesystem without actual locking primitives.
32
This defines two classes: ReadLock and WriteLock, which can be
33
implemented in different ways on different platforms. Both have an
37
from trace import mutter, note, warning
38
from errors import LockError
41
from bzrlib.trace import mutter, note, warning
42
from bzrlib.errors import LockError
44
class _base_Lock(object):
45
def _open(self, filename, filemode):
48
self.f = open(filename, filemode)
51
if e.errno != errno.ENOENT:
54
# maybe this is an old branch (before may 2005)
55
mutter("trying to create missing branch lock %r" % filename)
57
self.f = open(filename, 'wb')
63
from warnings import warn
64
warn("lock on %r not released" % self.f)
69
raise NotImplementedError()
76
############################################################
42
LOCK_SH = fcntl.LOCK_SH
43
LOCK_EX = fcntl.LOCK_EX
44
LOCK_NB = fcntl.LOCK_NB
53
fcntl.flock(f, fcntl.LOCK_UN)
83
class _fcntl_FileLock(_base_Lock):
87
fcntl.flock(self.f, fcntl.LOCK_UN)
92
class _fcntl_WriteLock(_fcntl_FileLock):
93
def __init__(self, filename):
95
fcntl.flock(self._open(filename, 'wb'), fcntl.LOCK_EX)
100
class _fcntl_ReadLock(_fcntl_FileLock):
101
def __init__(self, filename):
103
fcntl.flock(self._open(filename, 'rb'), fcntl.LOCK_SH)
107
WriteLock = _fcntl_WriteLock
108
ReadLock = _fcntl_ReadLock
57
110
except ImportError:
59
112
import win32con, win32file, pywintypes
60
LOCK_SH = 0 # the default
61
LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
62
LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
67
hfile = win32file._get_osfhandle(f.fileno())
69
hfile = win32file._get_osfhandle(f)
70
overlapped = pywintypes.OVERLAPPED()
71
win32file.LockFileEx(hfile, flags, 0, 0x7fff0000, overlapped)
78
hfile = win32file._get_osfhandle(f.fileno())
80
hfile = win32file._get_osfhandle(f)
81
overlapped = pywintypes.OVERLAPPED()
82
win32file.UnlockFileEx(hfile, 0, 0x7fff0000, overlapped)
115
#LOCK_SH = 0 # the default
116
#LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
117
#LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
119
class _w32c_FileLock(_base_Lock):
120
def _lock(self, filename, openmode, lockmode):
122
self._open(filename, openmode)
123
self.hfile = win32file._get_osfhandle(self.f.fileno())
124
overlapped = pywintypes.OVERLAPPED()
125
win32file.LockFileEx(self.hfile, lockmode, 0, 0x7fff0000, overlapped)
131
overlapped = pywintypes.OVERLAPPED()
132
win32file.UnlockFileEx(self.hfile, 0, 0x7fff0000, overlapped)
140
class _w32c_ReadLock(_w32c_FileLock):
141
def __init__(self, filename):
142
_w32c_FileLock._lock(self, filename, 'rb', 0)
144
class _w32c_WriteLock(_w32c_FileLock):
145
def __init__(self, filename):
146
_w32c_FileLock._lock(self, filename, 'wb',
147
win32con.LOCKFILE_EXCLUSIVE_LOCK)
151
WriteLock = _w32c_WriteLock
152
ReadLock = _w32c_ReadLock
85
154
except ImportError:
88
159
# Unfortunately, msvcrt.locking() doesn't distinguish between
89
160
# read locks and write locks. Also, the way the combinations
90
161
# work to get non-blocking is not the same, so we
91
162
# have to write extra special functions here.
165
class _msvc_FileLock(_base_Lock):
173
class _msvc_ReadLock(_msvc_FileLock):
174
def __init__(self, filename):
175
_msvc_lock(self._open(filename, 'rb'), self.LOCK_SH)
178
class _msvc_WriteLock(_msvc_FileLock):
179
def __init__(self, filename):
180
_msvc_lock(self._open(filename, 'wb'), self.LOCK_EX)
184
def _msvc_lock(f, flags):
99
186
# Unfortunately, msvcrt.LK_RLCK is equivalent to msvcrt.LK_LOCK
100
187
# according to the comments, LK_RLCK is open the lock for writing.