Found an issue in a Crystal + uing/libui-ng GUI app where Process.run does not return when called from a background worker while UIng.main is running.
Environment
- Crystal: 1.21.0
- OS: macOS
- GUI: uing / libui-ng
Behavior
Expected:
before Process.run
after Process.run: 0
Actual:
The child process exits, but Process.run / Process#wait never returns.
I confirmed:
Process.run("true") works outside UIng.main
LibC.system("true") works in the same GUI worker context
ps shows no remaining child process
- Calling
Crystal::System::SignalChildHandler.call periodically from UIng.timer makes Process.run return
Minimal reproduction
require "uing"
UIng.init
window = UIng::Window.new("probe", 300, 100, menubar: false, margined: true)
box = UIng::Box.new(:vertical, padded: true)
button = UIng::Button.new("Run")
label = UIng::Label.new("Ready")
button.on_clicked do
label.text = "Running..."
Fiber::ExecutionContext::Parallel.new("probe", 2).spawn do
puts "before Process.run"
status = Process.run("true")
puts "after Process.run: #{status.exit_code}"
UIng.queue_main do
label.text = "Done"
end
end
end
box.append(label, false)
box.append(button, false)
window.set_child(box)
window.show
UIng.main
UIng.uninit
Notes
My current workaround is to avoid Crystal Process.run / Process#wait in the GUI path and use POSIX popen/pclose/fgets instead.
It looks like Crystal’s SIGCHLD handling is not being pumped while uiMain owns the main loop. I’m not sure whether this should be handled in uing/libui-ng integration or considered a Crystal runtime limitation with external GUI main loops.
Found an issue in a Crystal + uing/libui-ng GUI app where
Process.rundoes not return when called from a background worker whileUIng.mainis running.Environment
Behavior
Expected:
Actual:
The child process exits, but
Process.run/Process#waitnever returns.I confirmed:
Process.run("true")works outsideUIng.mainLibC.system("true")works in the same GUI worker contextpsshows no remaining child processCrystal::System::SignalChildHandler.callperiodically fromUIng.timermakesProcess.runreturnMinimal reproduction
Notes
My current workaround is to avoid Crystal
Process.run/Process#waitin the GUI path and use POSIXpopen/pclose/fgetsinstead.It looks like Crystal’s SIGCHLD handling is not being pumped while
uiMainowns the main loop. I’m not sure whether this should be handled in uing/libui-ng integration or considered a Crystal runtime limitation with external GUI main loops.