Project

General

Profile

Feature #12693

Want a way to receive EINTR on Process.waitpid

Added by sonots (Naotoshi Seo) over 3 years ago. Updated over 3 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:77007]

Description

http://man7.org/linux/man-pages/man2/waitpid.2.html tells EINTR error if WNOHANG flag was not set and an unblocked signal or a SIGCHLD was caught.

However, ruby implementation of Process.waitpid does not raise EINTR https://github.com/ruby/ruby/blob/c2bf7e6f7d2fbe0b50da59aaa1374222f233aa71/process.c#L910-L911

test.rb

puts Process.pid

trap(:CONT) do
  puts 'CONT'
end

_pid = fork do
  sleep 10
end

Process.waitpid(-1)
$ ruby test.rb
$ kill -CONT xxxx # waitpid does not raise EINTR

I want a way or an option to get EINTR error on sending signal so that I can release blocking of waitpid.
It is same for wait, waitpid2, wait2, too.

History

Updated by sonots (Naotoshi Seo) over 3 years ago

  • Subject changed from Want to a way to receive EINTR on Process.waitpid to Want a way to receive EINTR on Process.waitpid

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

Naotoshi Seo wrote:

However, ruby implementation of Process.waitpid does not raise EINTR

No you don't. It is an extremely bad idea to use signal to interrupt execution.

Is it you must use signal for some reason or you just want to avoid infinite blocking? What if, for instance waitpid would take extra argument as timeout?

Updated by sonots (Naotoshi Seo) over 3 years ago

I am currently using Timeout hack for when I wanted to get EINTR like https://github.com/sonots/ruby-server-starter/blob/7fbc8db2548c215aae02afef385caa683040bd8a/lib/server/starter.rb#L215-L223.

I was glad if I did not need to write such a hacky code.

Updated by sonots (Naotoshi Seo) over 3 years ago

If adding an option to raise EINTR is not acceptable, adding timeout option is acceptable for my case.

Updated by naruse (Yui NARUSE) over 3 years ago

You can raise exception on main threadh by Thread.main.raise in trap.

Updated by sonots (Naotoshi Seo) over 3 years ago

It worked like a charm :)

test.rb

puts Process.pid

trap(:CONT) do
  raise 'CONT'
end

_pid = fork do
  sleep 10
end

begin
  Process.waitpid(-1)
rescue => e
  puts e.backtrace.join("\n")
end

Sending signal, I got

test.rb:4:in `block in <main>'
test.rb:12:in `waitpid'
test.rb:12:in `<main>'

Updated by sonots (Naotoshi Seo) over 3 years ago

  • Status changed from Open to Rejected

Also available in: Atom PDF