Skip to content

Doesn't work with non-blocking fibers #14

Description

@u3shit

I'm trying this little example, with the help of the async gem on ruby 3.1.3p185 on linux:

require 'async'
require 'proc/wait3'

Async do |tsk|
  pid = fork { sleep 2; exit! 2 }
  p Time.now
  t2 = tsk.async { Process.wait4 pid }
  p Time.now

  t2.wait
  p Time.now
end

I'd expect the first two p Time.now to print roughly the same time, then the third one two seconds later, but instead I get

2023-02-22 20:24:36.639229529 +0100
2023-02-22 20:24:38.641093571 +0100
2023-02-22 20:24:38.641145659 +0100

If I replace Process.wait4 with Process.wait, it works, but of course I don't get the resource usage stats that way.
I've tried to workaround this problem by putting the wait4 call into a different thread, but that didn't work either since this gem doesn't release the GVL while calling wait4 and friends.

...Actually, I'm not sure whether this can be solved at all, both non-blocking fibers and the process handling in ruby is a mess. Fiber::Scheduler is a monolithic piece, I think you'd need to add new methods here to support wait3/wait4, then update all Fiber::Scheduler implementations. Not likely to happen without having official support for wait3/wait4 in ruby.
Process handling is also a mess, sometimes it registers a SIGCHLD handler and uses that instead of waitpid, and bad things can happen if you fork/wait behind process.c's back. (Once I tried to write some code that calls clone on Linux. Half of the stuff you're supposed to call when forking is not exposed from libruby, and if you don't call them, you'll have random deadlocks later.)

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