From 0a11ed378184434647e1edd9ad5a8002f3a17e58 Mon Sep 17 00:00:00 2001 From: George Tsiamasiotis Date: Mon, 23 Sep 2024 22:22:46 +0300 Subject: [PATCH] Reopen stdout/err on process fork This helps avoid deadlocks (https://github.com/python/cpython/issues/91776). --- frigate/log.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frigate/log.py b/frigate/log.py index 475be50d4..b1f7c9af8 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -2,6 +2,7 @@ import atexit import logging import multiprocessing as mp import os +import sys import threading from collections import deque from contextlib import AbstractContextManager, ContextDecorator @@ -68,6 +69,19 @@ class log_thread(AbstractContextManager, ContextDecorator): self._stop_thread() +# When a multiprocessing.Process exits, python tries to flush stdout and stderr. However, if the +# process is created after a thread (for example a logging thread) is created and the process fork +# happens while an internal lock is held, the stdout/err flush can cause a deadlock. +# +# https://github.com/python/cpython/issues/91776 +def reopen_std_streams(): + sys.stdout = os.fdopen(1, "w") + sys.stderr = os.fdopen(2, "w") + + +os.register_at_fork(after_in_child=reopen_std_streams) + + # based on https://codereview.stackexchange.com/a/17959 class LogPipe(threading.Thread): def __init__(self, log_name: str):