This commit is contained in:
2026-03-26 23:00:25 -07:00
parent 562acd809c
commit 37bb4ca685
8 changed files with 368 additions and 123 deletions

View File

@@ -1172,6 +1172,11 @@ def _get_ipc_lock_path(ipc_path: str) -> Path:
return lock_dir / f"medeia-mpv-helper-{safe}.lock"
def _get_ipc_lock_meta_path(ipc_path: str) -> Path:
lock_path = _get_ipc_lock_path(ipc_path)
return lock_path.with_suffix(lock_path.suffix + ".json")
def _read_lock_file_pid(ipc_path: str) -> Optional[int]:
"""Return the PID recorded in the lock file by the current holder, or None.
@@ -1181,7 +1186,7 @@ def _read_lock_file_pid(ipc_path: str) -> Optional[int]:
avoiding the race where concurrent sibling helpers all kill each other.
"""
try:
lock_path = _get_ipc_lock_path(ipc_path)
lock_path = _get_ipc_lock_meta_path(ipc_path)
with open(str(lock_path), "r", encoding="utf-8", errors="replace") as fh:
content = fh.read().strip()
if not content:
@@ -1193,6 +1198,57 @@ def _read_lock_file_pid(ipc_path: str) -> Optional[int]:
return None
def _write_lock_file_metadata(ipc_path: str) -> None:
meta_path = _get_ipc_lock_meta_path(ipc_path)
meta_path.write_text(
json.dumps(
{
"pid": os.getpid(),
"version": MEDEIA_MPV_HELPER_VERSION,
"ipc": str(ipc_path),
"started_at": int(time.time()),
},
ensure_ascii=False,
),
encoding="utf-8",
errors="replace",
)
def _release_ipc_lock(fh: Any, ipc_path: Optional[str] = None) -> None:
if fh is None:
if ipc_path:
try:
_get_ipc_lock_meta_path(ipc_path).unlink(missing_ok=True)
except Exception:
pass
return
try:
if os.name == "nt":
import msvcrt # type: ignore
try:
fh.seek(0)
except Exception:
pass
msvcrt.locking(fh.fileno(), msvcrt.LK_UNLCK, 1)
else:
import fcntl # type: ignore
fcntl.flock(fh.fileno(), fcntl.LOCK_UN)
except Exception:
pass
try:
fh.close()
except Exception:
pass
if ipc_path:
try:
_get_ipc_lock_meta_path(ipc_path).unlink(missing_ok=True)
except Exception:
pass
def _acquire_ipc_lock(ipc_path: str) -> Optional[Any]:
"""Best-effort singleton lock per IPC path.
@@ -1238,6 +1294,11 @@ def _acquire_ipc_lock(ipc_path: str) -> Optional[Any]:
pass
return None
try:
_write_lock_file_metadata(ipc_path)
except Exception:
pass
return fh
except Exception:
return None
@@ -1433,20 +1494,7 @@ def main(argv: Optional[list[str]] = None) -> int:
f"[helper] version={MEDEIA_MPV_HELPER_VERSION} started ipc={args.ipc}"
)
try:
_lock_fh.seek(0)
_lock_fh.truncate()
_lock_fh.write(
json.dumps(
{
"pid": os.getpid(),
"version": MEDEIA_MPV_HELPER_VERSION,
"ipc": str(args.ipc),
"started_at": int(time.time()),
},
ensure_ascii=False,
)
)
_lock_fh.flush()
_write_lock_file_metadata(str(args.ipc))
except Exception:
pass
try:
@@ -2103,6 +2151,10 @@ def main(argv: Optional[list[str]] = None) -> int:
client.disconnect()
except Exception:
pass
try:
_release_ipc_lock(_lock_fh, str(args.ipc))
except Exception:
pass
return 0