From 8a7b717a467f35752224f1bda535fe34466ab2ed Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sun, 15 Dec 2024 23:51:42 +1300 Subject: [PATCH] `process_wait` can hang if reusing FD in rapid succession. (#126) * Failing test case. * Unique per-pid/file descriptor. --- ext/io/event/selector/epoll.c | 2 +- test/io/event/selector.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ext/io/event/selector/epoll.c b/ext/io/event/selector/epoll.c index 611c996..c1a07ee 100644 --- a/ext/io/event/selector/epoll.c +++ b/ext/io/event/selector/epoll.c @@ -519,7 +519,7 @@ VALUE IO_Event_Selector_EPoll_process_wait(VALUE self, VALUE fiber, VALUE _pid, RB_OBJ_WRITTEN(self, Qundef, fiber); - int result = IO_Event_Selector_EPoll_Waiting_register(selector, 0, descriptor, &waiting); + int result = IO_Event_Selector_EPoll_Waiting_register(selector, _pid, descriptor, &waiting); if (result == -1) { close(descriptor); diff --git a/test/io/event/selector.rb b/test/io/event/selector.rb index 1d9da05..91a189c 100644 --- a/test/io/event/selector.rb +++ b/test/io/event/selector.rb @@ -581,6 +581,32 @@ def transfer expect(events).to be == [:process_finished] expect(result).to be(:success?) end + + it "can wait for two processes sequentially" do + result1 = result2 = nil + events = [] + + fiber = Fiber.new do + pid1 = Process.spawn("sleep 0.001") + pid2 = Process.spawn("sleep 0.001") + + result1 = selector.process_wait(Fiber.current, pid1, 0) + events << :process_finished1 + + result2 = selector.process_wait(Fiber.current, pid2, 0) + events << :process_finished2 + end + + fiber.transfer + + while fiber.alive? + selector.select(0) + end + + expect(events).to be == [:process_finished1, :process_finished2] + expect(result1).to be(:success?) + expect(result2).to be(:success?) + end end with "#resume" do