# HG changeset patch # User Michael Granger # Date 1562786425 25200 # Wed Jul 10 12:20:25 2019 -0700 # Node ID 0ef3f6d5eb40e7f9c9ff874b9e7f9c0615b75068 # Parent 429095a763a1ec94fcb95f1ae437c1438725b9ef Work around CZTop's mapping of EINTR to Interrupt diff --git a/lib/cztop/reactor.rb b/lib/cztop/reactor.rb --- a/lib/cztop/reactor.rb +++ b/lib/cztop/reactor.rb @@ -36,6 +36,14 @@ write: CZTop::Poller::ZMQ::POLLOUT, }.freeze + # Errors encountered during the poll that should retry instead of raising + POLLER_RETRY_ERRORS = [ + Errno::EINTR::Errno, # CZTop maps this to Interrupt, but it can be *any* + # signal, not just SIGINT + Errno::EAGAIN::Errno, + Errno::ETIMEDOUT::Errno, + ] + autoload :Event, 'cztop/reactor/event' @@ -393,7 +401,10 @@ def wait( timeout=-1 ) rc = CZTop::Poller::ZMQ.poller_wait( @poller_ptr, @event_ptr, timeout ) if rc == -1 - if CZMQ::FFI::Errors.errno != Errno::ETIMEDOUT::Errno + case CZMQ::FFI::Errors.errno + when *POLLER_RETRY_ERRORS + # Retry if the error means we should + else CZTop::HasFFIDelegate.raise_zmq_err end return nil diff --git a/spec/cztop/reactor_spec.rb b/spec/cztop/reactor_spec.rb --- a/spec/cztop/reactor_spec.rb +++ b/spec/cztop/reactor_spec.rb @@ -364,6 +364,16 @@ end + it "ignores EINTR by default" do + expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ). + and_return( -1 ) + expect( CZMQ::FFI::Errors ).to receive( :errno ). + and_return( Errno::EINTR::Errno ) + + expect( reactor.poll_once ).to be_nil + end + + it "has an option to propagate EGAIN/EWOULDBLOCK" do expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ). and_raise( Errno::EAGAIN.new )