add # 新增对资源文件的维护

This commit is contained in:
2026-10-26 18:54:19 +08:00
parent 72e54c3573
commit b41db58ea5
790 changed files with 14534 additions and 2 deletions
+50
View File
@@ -0,0 +1,50 @@
"""Serialize publishers for one output; process exit releases OS locks."""
from contextlib import contextmanager
import errno
import os
import threading
import time
_LOCKS = {}
_REGISTRY_GUARD = threading.Lock()
@contextmanager
def publication_lock(output):
key = os.path.normcase(str(output.resolve()))
with _REGISTRY_GUARD:
local = _LOCKS.setdefault(key, threading.Lock())
# Some OS record locks are process-scoped, so threads also need a mutex.
with local:
output.mkdir(parents=True, exist_ok=True)
# Keep this inode/path permanently: unlinking it could split waiters
# between different locks. It contains no publication state or secrets.
with (output / ".publish.lock").open("a+b") as stream:
if os.name == "nt":
import msvcrt
if os.fstat(stream.fileno()).st_size == 0:
stream.write(b"\0")
stream.flush()
stream.seek(0)
while True:
try:
msvcrt.locking(stream.fileno(), msvcrt.LK_NBLCK, 1)
break
except OSError as error:
if error.errno not in (errno.EACCES, errno.EAGAIN,
errno.EDEADLK):
raise
time.sleep(0.05)
try:
yield
finally:
stream.seek(0)
msvcrt.locking(stream.fileno(), msvcrt.LK_UNLCK, 1)
else:
import fcntl
fcntl.flock(stream.fileno(), fcntl.LOCK_EX)
try:
yield
finally:
fcntl.flock(stream.fileno(), fcntl.LOCK_UN)