zeromq / rbzmq

Ruby binding for 0MQ
http://www.zeromq.org/bindings:ruby
247 stars 43 forks source link

Signal handling issue with ruby 1.8.7 #8

Open fjnl opened 13 years ago

fjnl commented 13 years ago

With ruby 1.8.7, zmq 2.1.7 and rbzmq 2.1.3, I notice that rbzmq has signal handling problem. With ruby 1.9.2, this problem is not occurred.

Reproduction code is below.

require 'rubygems'
require 'zmq'

c = ZMQ::Context.new
s = c.socket(ZMQ::PULL)
s.bind('ipc:///tmp/a')

begin
  puts s.recv
ensure
  $stderr.puts 'ensure'
  s.close
  c.close
end

When I input Ctrl-c and terminate this program while blocking in s.recv, I expect the ensure closure is run and 'ensure' is shown in the terminal but actual output is below.

$ ruby intr.rb
^Cintr.rb:11: Interrupt

The line number of Interrupt is strange. Line 11 is '$stderr.puts ...'. I think EINTR is ignored because ruby vm will handle it. I've created a small patch for socket_recv. It seems fine but I don't know whether this is the best way.

diff --git a/rbzmq.c b/rbzmq.c
index 8164c93..d1929fc 100644
--- a/rbzmq.c
+++ b/rbzmq.c
@@ -1603,7 +1603,7 @@ static VALUE socket_recv (int argc_, VALUE* argv_, VALUE self_)
     else
 #endif
         rc = zmq_recv (s, &msg, flags);
-    if (rc != 0 && zmq_errno () == EAGAIN) {
+    if (rc != 0 && zmq_errno () == EAGAIN || zmq_errno () == EINTR) {
         rc = zmq_msg_close (&msg);
         assert (rc == 0);
         return Qnil;
bwbuchanan commented 13 years ago

Can you send a pull request, please?