[zeromq-dev] exception from recv()

Tom Wilberding tom at wilberding.com
Thu Sep 27 17:11:23 CEST 2012


> On Wed, Sep 26, 2012 at 5:46 PM, Tom Wilberding <tom at wilberding.com>
> wrote:
> >> * Blocking calls now return EINTR if interrupted by the delivery of
> a
> >>   signal; this also means that language bindings which previously
> had
> >>   problems with handling SIGINT/^C should now work correctly.
> >
> > What is the best practice for handling this in C++? The zmq.hpp
> wrapper
> > is throwing without any additional info when zmq_recv() returns -1
> and
> > errno is EINTR, so should my app be catching this exception? And if
> so,
> > shouldn't information pertaining to the root cause of the interrupt
> be
> > passed along?
> 
> It's throwing if it *isn't* EINTR - catch it and use errnum or what()
> to see what the underlying issue is.
> 
> Ian 
> 

Thanks Ian but my reading of zmq.hpp and the release notes is that it is
throwing if it isn't EGAIN (not EINTR). I looked at the java bindings
they have similar logic.

> > inline bool recv (message_t *msg_, int flags_ = 0)
> >         {
> >             int rc = zmq_recv (ptr, msg_, flags_);
> >             if (rc == 0)
> >                 return true;
> >             if (rc == -1 && zmq_errno () == EAGAIN)
> >                 return false;
> >             throw error_t ();
> >         }
> 
> Looking at the release notes:
> 
> > * Blocking calls now return EINTR if interrupted by the delivery of
> a
> >   signal; this also means that language bindings which previously
> had
> >   problems with handling SIGINT/^C should now work correctly.

I found an old thread from 2010 when this change was originally being
discussed, but I'm still scratching my head. It seems like the C++
wrapper is throwing when a blocking zmq_recv() is now returning -1 and
errno == EINTR in 2.2.0, whereas in 2.0.10 zmq_recv() was not passing
this along.

http://lists.zeromq.org/pipermail/zeromq-dev/2010-September/005814.html

But having my application code blindly swallow the exception thrown by
the C++ binding makes me nervous unless the folks on this confirm that
this is best practice.

I suppose my application code can catch the exception and then inspect
zmq_errno() and move forward if it is EINTR and rethrow if it is
anything else, but honestly, that seems clunky so I feel like I am
missing something or doing something wrong.

I should also point out that I have no idea what is the root cause of
the interrupted system call. It can run for hours without it occurring,
but I've found a few ways to induce it to happen, so if anyone has some
debugging tips, I'd appreciate the help. I'm not sending SIGINT/^C to my
app, there is something else going on. Is receiving EINTR during a
zmq_recv() for anything other than a SIGINT/^C something that others are
familiar with? 

1) Perhaps my installation is corrupt in some way. I installed 2.2.0 and
did not explicitly uninstall 2.0.10 first
2) Is seeing errno == EINTR during a zmq_recv() call something I should
just ignore and keep trucking, or is this an exceptional case that
indicates a deeper issue?
3) Is any one else doing anything specific in there application to
handle interrupted zmq_recv()
4) should I install my own signal handler? I think I will do that next
as a debugging step, but I would not expect to do that in production.

Thanks,
Tom






More information about the zeromq-dev mailing list