zeromq / libzmq

ZeroMQ core engine in C++, implements ZMTP/3.1
https://www.zeromq.org
Mozilla Public License 2.0
9.53k stars 2.34k forks source link

Failed assertion due to `connect_inproc_sockets` during termination #4544

Open steplee opened 1 year ago

steplee commented 1 year ago

Issue description

I get error 'Resource temporarily unavailable' when calling zmq_cxt_term when using an inproc subscriber that never is matched with a bound publisher.

I narrowed the issue to zmq::ctx_t::connect_inproc_sockets(), specifically: this line

I think the read is failing because the context is in a partially shutdown state or something. At the bottom of the same function is a comment:

// When a ctx is terminated all pending inproc connection will be // connected, but the socket will already be closed and the pipe will be // in waiting_for_delimiter state, which means no more writes can be done // and the routing id write fails and causes an assert. Check if the socket // is open before sending.

I didn't have time to dig into what is going on, but simply adding the same second condition to the if statement surrounding the errant block, my issue is resolved:

if (!bind_options_.recv_routing_id
        && pending_connection_.endpoint.socket->check_tag ()) { // This is new
        msg_t msg;
        const bool ok = pending_connection_.bind_pipe->read (&msg);
        zmq_assert (ok); // This fails without the new second condition.
        const int rc = msg.close ();
        errno_assert (rc == 0);
    }

Environment

Minimal test code / Steps to reproduce the issue

Sorry, I tried a minimal case with one subscriber (connect) and no publisher (no bind), but it did not fail. Something in my more complex application is causing the issue.