@@ 36,6 36,14 @@ class CZTop::Reactor
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 @@ class CZTop::Reactor
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
@@ 364,6 364,16 @@ describe CZTop::Reactor do
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 )