From ea29718068c5339077d0900a57eb395917545703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Mon, 3 Mar 2025 18:09:38 +0100 Subject: [PATCH] Fix waiting on child processes blocking indefinitely (#15) --- lib/pythonx/application.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/pythonx/application.ex b/lib/pythonx/application.ex index a4b8053..1be6aa8 100644 --- a/lib/pythonx/application.ex +++ b/lib/pythonx/application.ex @@ -5,6 +5,8 @@ defmodule Pythonx.Application do @impl true def start(_type, _args) do + enable_sigchld() + children = [ Pythonx.Janitor ] @@ -26,4 +28,16 @@ defmodule Pythonx.Application do else defp maybe_uv_init(), do: :noop end + + defp enable_sigchld() do + # Some APIs in Python, such as subprocess.run, wait for a child + # OS process to finish. On Unix, this relies on `waitpid` C API, + # which does not work properly if SIGCHLD is ignored, resulting + # in infinite waiting. ERTS ignores the signal by default, so we + # explicitly restore the default handler. + case :os.type() do + {:win32, _osname} -> :ok + {:unix, _osname} -> :os.set_signal(:sigchld, :default) + end + end end