impuls/lib/python3.11/site-packages/fasteners/process_mechanism.py

155 lines
3.9 KiB
Python

from abc import ABC
from abc import abstractmethod
import errno
import os
class _InterProcessReaderWriterLockMechanism(ABC):
@staticmethod
@abstractmethod
def trylock(lockfile, exclusive):
...
@staticmethod
@abstractmethod
def unlock(lockfile):
...
@staticmethod
@abstractmethod
def get_handle(path):
...
@staticmethod
@abstractmethod
def close_handle(lockfile):
...
class _InterProcessMechanism(ABC):
@staticmethod
@abstractmethod
def trylock(lockfile):
...
@staticmethod
@abstractmethod
def unlock(lockfile):
...
class _WindowsInterProcessMechanism(_InterProcessMechanism):
"""Interprocess lock implementation that works on windows systems."""
@staticmethod
def trylock(lockfile):
fileno = lockfile.fileno()
msvcrt.locking(fileno, msvcrt.LK_NBLCK, 1)
@staticmethod
def unlock(lockfile):
fileno = lockfile.fileno()
msvcrt.locking(fileno, msvcrt.LK_UNLCK, 1)
class _FcntlInterProcessMechanism(_InterProcessMechanism):
"""Interprocess lock implementation that works on posix systems."""
@staticmethod
def trylock(lockfile):
fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
@staticmethod
def unlock(lockfile):
fcntl.lockf(lockfile, fcntl.LOCK_UN)
class _WindowsInterProcessReaderWriterLockMechanism(_InterProcessReaderWriterLockMechanism):
"""Interprocess readers writer lock implementation that works on windows
systems."""
@staticmethod
def trylock(lockfile, exclusive):
if exclusive:
flags = win32con.LOCKFILE_FAIL_IMMEDIATELY | win32con.LOCKFILE_EXCLUSIVE_LOCK
else:
flags = win32con.LOCKFILE_FAIL_IMMEDIATELY
handle = msvcrt.get_osfhandle(lockfile.fileno())
ok = win32file.LockFileEx(handle, flags, 0, 1, 0, win32file.pointer(pywintypes.OVERLAPPED()))
if ok:
return True
else:
last_error = win32file.GetLastError()
if last_error == win32file.ERROR_LOCK_VIOLATION:
return False
else:
raise OSError(last_error)
@staticmethod
def unlock(lockfile):
handle = msvcrt.get_osfhandle(lockfile.fileno())
ok = win32file.UnlockFileEx(handle, 0, 1, 0, win32file.pointer(pywintypes.OVERLAPPED()))
if not ok:
raise OSError(win32file.GetLastError())
@staticmethod
def get_handle(path):
return open(path, 'a+')
@staticmethod
def close_handle(lockfile):
lockfile.close()
class _FcntlInterProcessReaderWriterLockMechanism(_InterProcessReaderWriterLockMechanism):
"""Interprocess readers writer lock implementation that works on posix
systems."""
@staticmethod
def trylock(lockfile, exclusive):
if exclusive:
flags = fcntl.LOCK_EX | fcntl.LOCK_NB
else:
flags = fcntl.LOCK_SH | fcntl.LOCK_NB
try:
fcntl.lockf(lockfile, flags)
return True
except (IOError, OSError) as e:
if e.errno in (errno.EACCES, errno.EAGAIN):
return False
else:
raise e
@staticmethod
def unlock(lockfile):
fcntl.lockf(lockfile, fcntl.LOCK_UN)
@staticmethod
def get_handle(path):
return open(path, 'a+')
@staticmethod
def close_handle(lockfile):
lockfile.close()
if os.name == 'nt':
import msvcrt
import fasteners.pywin32.pywintypes as pywintypes
import fasteners.pywin32.win32con as win32con
import fasteners.pywin32.win32file as win32file
_interprocess_reader_writer_mechanism = _WindowsInterProcessReaderWriterLockMechanism()
_interprocess_mechanism = _WindowsInterProcessMechanism()
else:
import fcntl
_interprocess_reader_writer_mechanism = _FcntlInterProcessReaderWriterLockMechanism()
_interprocess_mechanism = _FcntlInterProcessMechanism()