Ruby and SIGVTALRM

  • Thread starter Joshua Haberman
  • Start date
J

Joshua Haberman

Hi,

Why would SIGVTALRM ever cause IO#sysread to throw EINTR? I'm having
a problem where a Net::HTTP connection is repeatedly dying because its
IO#sysread call is being interrupted and raising EINTR. I have
attached strace to the process, and verified that the signal being
raised is SIGVTALRM.

What I don't understand is why SIGVTALRM would ever interrupt a system
call. the setitimer(2) documentation says that the ITIMER_VIRTUAL
timer *only* decrements when the process is executing. So why would
the signal fire when I'm blocked on a system call (eg. when my process
is *not* executing)?

I notice that up until recently, signal handlers for all signals
except SIGVTALRM were installed with the SA_RESTART flag, which would
make read(2) retry instead of returning EINTR when a signal was
received. (I'm still using a version of Ruby that has this
behavior). Why did Ruby specifically *not* set SA_RESTART for
SIGVTALRM? I'm guessing the rationale has something to do with
allowing Ruby to run its thread scheduler. But this doesn't make
sense to me for two reasons:

1. the Ruby interpreter already takes measures to ensure that it never
blocks on a system call if there are other runnable threads. So when
would it ever be blocked on a system call, but have other threads it
wants to schedule by receiving SIGVTALRM?

2. again, according to the setitimer(2) documentation, it doesn't make
sense that SIGVTALRM would ever be raised when blocked on a system
call. So why should not setting SA_RESTART have any effect?

Any help is much appreciated!

Josh

P.S. Does the change in 1.8.6 of not setting SA_RESTART with
sigaction(2) mean that Ruby scripts now need to handle EINTR in many
places they did not previously have to?
 
P

Paul Brannan

Hi,

Why would SIGVTALRM ever cause IO#sysread to throw EINTR? I'm having
a problem where a Net::HTTP connection is repeatedly dying because its
IO#sysread call is being interrupted and raising EINTR. I have
attached strace to the process, and verified that the signal being
raised is SIGVTALRM.

Which platform are you running on and which version of ruby are you
running?

Do you have a small test case that can reproduce the problem?
P.S. Does the change in 1.8.6 of not setting SA_RESTART with
sigaction(2) mean that Ruby scripts now need to handle EINTR in many
places they did not previously have to?

This appears to be the case, but I haven't tested it. Looks like maybe
this was changed in response to [ruby-talk:133002].

Incidentally, one of my coworkers has recently found some cases in the
python standard library that didn't handle EINTR correctly. It's easy
to neglect if you aren't thinking about it.

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top