349
358
_lock_classes.append(('fcntl', _fcntl_WriteLock, _fcntl_ReadLock))
361
if have_pywin32 and sys.platform == 'win32':
362
win32file_CreateFile = win32file.CreateFileW
364
class _w32c_FileLock(_OSLock):
366
def _open(self, filename, access, share, cflags, pymode):
367
self.filename = osutils.realpath(filename)
369
self._handle = win32file_CreateFile(
370
filename, access, share, None, win32file.OPEN_ALWAYS,
371
win32file.FILE_ATTRIBUTE_NORMAL, None)
372
except pywintypes.error as e:
373
if e.args[0] == winerror.ERROR_ACCESS_DENIED:
374
raise errors.LockFailed(filename, e)
375
if e.args[0] == winerror.ERROR_SHARING_VIOLATION:
376
raise errors.LockContention(filename, e)
378
fd = win32file._open_osfhandle(self._handle, cflags)
379
self.f = os.fdopen(fd, pymode)
386
class _w32c_ReadLock(_w32c_FileLock):
387
def __init__(self, filename):
388
super(_w32c_ReadLock, self).__init__()
389
self._open(filename, win32file.GENERIC_READ,
390
win32file.FILE_SHARE_READ, os.O_RDONLY, "rb")
392
def temporary_write_lock(self):
393
"""Try to grab a write lock on the file.
395
On platforms that support it, this will upgrade to a write lock
396
without unlocking the file.
397
Otherwise, this will release the read lock, and try to acquire a
400
:return: A token which can be used to switch back to a read lock.
402
# I can't find a way to upgrade a read lock to a write lock without
403
# unlocking first. So here, we do just that.
406
wlock = _w32c_WriteLock(self.filename)
407
except errors.LockError:
408
return False, _w32c_ReadLock(self.filename)
411
class _w32c_WriteLock(_w32c_FileLock):
412
def __init__(self, filename):
413
super(_w32c_WriteLock, self).__init__()
415
win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0,
418
def restore_read_lock(self):
419
"""Restore the original ReadLock."""
420
# For win32 we had to completely let go of the original lock, so we
421
# just unlock and create a new read lock.
423
return _w32c_ReadLock(self.filename)
425
_lock_classes.append(('pywin32', _w32c_WriteLock, _w32c_ReadLock))
352
428
if have_ctypes_win32:
353
429
from ctypes.wintypes import DWORD, LPWSTR
354
430
LPSECURITY_ATTRIBUTES = ctypes.c_void_p # used as NULL no need to declare