From f089ae250898020631c8636a725bb11f5206b852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Tue, 4 Mar 2025 02:04:14 +0900 Subject: [PATCH] Fix waiting on child processes blocking indefinitely --- 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