Files
aios/services/aios-single-owner-governance/aios_single_owner_governance/lock.py
T

48 lines
1.5 KiB
Python

from __future__ import annotations
from pathlib import Path
try:
import fcntl
except ImportError: # pragma: no cover - exercised by Windows validation
fcntl = None
import msvcrt
class MaintenanceLock:
"""Process fence used only by fixture and later approved activation executors."""
def __init__(self, path: Path) -> None:
self.path = path
self._handle = None
def __enter__(self) -> "MaintenanceLock":
self.path.parent.mkdir(parents=True, exist_ok=True)
self._handle = self.path.open("a+")
if fcntl is not None:
try:
fcntl.flock(self._handle.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except BlockingIOError:
self._handle.close()
self._handle = None
raise
else:
self._handle.seek(0)
try:
msvcrt.locking(self._handle.fileno(), msvcrt.LK_NBLCK, 1)
except OSError as exc:
self._handle.close()
self._handle = None
raise BlockingIOError("maintenance lock held") from exc
return self
def __exit__(self, exc_type, exc, tb) -> None:
if self._handle is not None:
if fcntl is not None:
fcntl.flock(self._handle.fileno(), fcntl.LOCK_UN)
else:
self._handle.seek(0)
msvcrt.locking(self._handle.fileno(), msvcrt.LK_UNLCK, 1)
self._handle.close()
self._handle = None