Based on LockFile / UnlockFile from win32 API https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202(v=vs.85).aspx
| 64 | |
| 65 | |
| 66 | class _WinFileLock(AbstractFileLock): |
| 67 | """ |
| 68 | Based on LockFile / UnlockFile from win32 API |
| 69 | https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202(v=vs.85).aspx |
| 70 | """ |
| 71 | |
| 72 | _LOCKED_BYTES_NUM = 1 |
| 73 | |
| 74 | def __init__(self, path): |
| 75 | super(_WinFileLock, self).__init__(path) |
| 76 | # nonbuffered random access rw mode |
| 77 | self._lock = os.fdopen(os.open(self.path, os.O_RDWR | os.O_CREAT | os.O_BINARY | os.O_NOINHERIT), 'r+b', 0) |
| 78 | try: |
| 79 | self._lock.write(b' ' * self._LOCKED_BYTES_NUM) |
| 80 | except IOError as e: |
| 81 | if e.errno != errno.EACCES or not os.path.isfile(path): |
| 82 | raise |
| 83 | |
| 84 | def acquire(self, blocking=True): |
| 85 | locked = False |
| 86 | while not locked: |
| 87 | locked = library.python.windows.lock_file(self._lock, 0, self._LOCKED_BYTES_NUM, raises=False) |
| 88 | if locked: |
| 89 | return True |
| 90 | if blocking: |
| 91 | time.sleep(0.5) |
| 92 | else: |
| 93 | return False |
| 94 | |
| 95 | def release(self): |
| 96 | if self._lock: |
| 97 | library.python.windows.unlock_file(self._lock, 0, self._LOCKED_BYTES_NUM, raises=False) |
| 98 | |
| 99 | def __del__(self): |
| 100 | if getattr(self, '_lock', False): |
| 101 | self._lock.close() |
| 102 | |
| 103 | |
| 104 | class FileLock(AbstractFileLock): |