cppzmq icon indicating copy to clipboard operation
cppzmq copied to clipboard

send has ambiguous error/success return

Open oblitum opened this issue 8 years ago • 5 comments

        inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_send (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

For nbytes == 0 (e.g. for parts with size zero), the return is zero, but it's success. Nonetheless, a zero return is being used to mean EAGAIN.

oblitum avatar Nov 16 '15 17:11 oblitum

Why are you calling send when you know your buffer doesn't have anything to send?

mwpowellhtx avatar Nov 16 '15 17:11 mwpowellhtx

@mwpowellhtx my particular case relates with sending file contents as a message part, and I didn't bother to have additional logic for exceptional messages when files are empty, it should follow the same logic. I guess this shouldn't need special treatment and it seems ZMQ raw api supports this since it allows for zero return with success and reserves -1 return to mean any error.

oblitum avatar Nov 16 '15 17:11 oblitum

Hello,

I agree that the behavior is not great, especially since it is not coherent with the bool send() function, which returns false on EAGAIN and true on 0 bytes sent.

I am not sure however what the appropriate fix would be:

  • Changing the return type to int, and return -1 on EAGAIN.
  • Throw on EAGAIN (I don't like this)
  • Any idea?

xaqq avatar Dec 11 '15 15:12 xaqq

I have also a question in this direction: Dealer Socket which is not connected sends a message out. Result: I get "40 bytes send" back and the function returns true, although an error is set. This is somehow misleading.

nbytes: 40, errno: Resource temporarily unavailable

` inline bool send(message_t &msg_, int flags_ = 0)

{
    int nbytes = zmq_msg_send(&(msg_.msg), ptr, flags_);
    std::cerr << "nbytes: " << nbytes << ", errno: " << zmq_strerror (zmq_errno()) << std::endl;
    if (nbytes >= 0)
        return true;
    if (zmq_errno() == EAGAIN)
        return false;
    throw error_t();
}

`

maxlein avatar Oct 15 '18 14:10 maxlein

@maxlein I don't think this is a question related to cppzmq, but to libzmq itself. But I think in general errno must only be evaluated after a function has indicated an error (which, for zmq_msg_send would be the case if it retuned -1). Otherwise, the value of errno is undefined.

sigiesec avatar Oct 17 '18 16:10 sigiesec