From 7373d2362a8d7baea516026b7e135e8ce6048531 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 5 Apr 2025 13:15:05 +0530 Subject: [PATCH] Fork to handle quicklook clients --- src/calibre/srv/render_book.py | 20 ++++++++++++++++++-- src/calibre/utils/safe_atexit.py | 6 ++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/calibre/srv/render_book.py b/src/calibre/srv/render_book.py index f9343f1194..d592a26773 100644 --- a/src/calibre/srv/render_book.py +++ b/src/calibre/srv/render_book.py @@ -909,18 +909,34 @@ def quicklook_service(path_to_socket: str) -> None: ''' import socket from contextlib import closing, suppress + + from calibre.constants import debug + from calibre.ptempfile import reset_base_dir + from calibre.utils.safe_atexit import remove_file_atexit, reset_after_fork + debug(False) s = socket.socket(socket.AF_UNIX) s.setblocking(True) s.bind(path_to_socket) with suppress(KeyboardInterrupt), closing(s): if path_to_socket and not path_to_socket.startswith('\0'): - from calibre.utils.safe_atexit import remove_file_atexit remove_file_atexit(path_to_socket) s.listen(16) while True: c, addr = s.accept() c.setblocking(True) - handle_quicklook_client(c) + os.set_inheritable(c.fileno(), True) + if child_pid := os.fork(): # parent + c.close() + os.waitpid(child_pid, 0) + else: # child + os.set_inheritable(c.fileno(), False) + reset_after_fork() + reset_base_dir() + try: + handle_quicklook_client(c) + finally: + c.shutdown(socket.SHUT_RDWR) + c.close() class Profiler: diff --git a/src/calibre/utils/safe_atexit.py b/src/calibre/utils/safe_atexit.py index bd85806563..8785c0ff66 100644 --- a/src/calibre/utils/safe_atexit.py +++ b/src/calibre/utils/safe_atexit.py @@ -66,6 +66,12 @@ def ensure_worker(): return worker +def reset_after_fork(): + global worker + atexit.unregister(close_worker) + worker = None + + def _send_command(action: str, payload: str) -> None: worker = ensure_worker() worker.stdin.write(json.dumps({'action': action, 'payload': payload}).encode('utf-8'))