Skip to content

Process.run / Process#wait does not return while UIng.main is running #32

Description

@kojix2

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:

before Process.run

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions