gamemode-watch: single-instance flock guard
Prevents a manually-launched watcher and the spawn-at-startup one from racing the same winwatch source; the second instance exits immediately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,9 @@ Launched at niri startup (spawn-at-startup "gamemode-watch"). Reconnects if the
|
|||||||
event stream drops while niri is still alive, and always releases the source on
|
event stream drops while niri is still alive, and always releases the source on
|
||||||
exit so gamemode can never get stuck on when the watcher stops.
|
exit so gamemode can never get stuck on when the watcher stops.
|
||||||
"""
|
"""
|
||||||
|
import fcntl
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -133,7 +135,23 @@ def _on_sigterm(signum, frame):
|
|||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
def acquire_single_instance():
|
||||||
|
# Hold an exclusive lock so a second watcher (e.g. spawn-at-startup plus a
|
||||||
|
# manual launch) exits instead of racing the same winwatch source. The open
|
||||||
|
# file must stay referenced for the process lifetime to keep the lock.
|
||||||
|
rt = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
|
||||||
|
f = open(os.path.join(rt, "gamemode-watch.lock"), "w")
|
||||||
|
try:
|
||||||
|
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
except OSError:
|
||||||
|
return None
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
_lock = acquire_single_instance()
|
||||||
|
if _lock is None:
|
||||||
|
sys.exit(0) # another instance already running
|
||||||
signal.signal(signal.SIGTERM, _on_sigterm)
|
signal.signal(signal.SIGTERM, _on_sigterm)
|
||||||
try:
|
try:
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user