# Ruby and SIGVTALRM

**URL:** <https://www.ruby-forum.com/t/ruby-and-sigvtalrm/103189>\
**Category:** Ruby\
**Created:** [May 2, 2007, 7:50pm UTC](https://www.ruby-forum.com/t/ruby-and-sigvtalrm/103189 "2007-05-02T19:50:57Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![joshmh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5fc32e/32.png) [@joshmh](https://www.ruby-forum.com/u/joshmh)\
**Post date:** [May 2, 2007, 7:50pm UTC](https://www.ruby-forum.com/t/ruby-and-sigvtalrm/103189/1 "2007-05-02T19:50:57Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![joshmh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5fc32e/32.png) [@joshmh](https://www.ruby-forum.com/u/joshmh)\
**Post date:** [May 3, 2007, 7:41pm UTC](https://www.ruby-forum.com/t/ruby-and-sigvtalrm/103189/2 "2007-05-03T19:41:50Z")

</div>

On Thu, May 03, 2007 at 02:50:04AM +0900, Joshua H. wrote:

> 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
