In one of my applications I'm using DEALER/ROUTER inproc connections. I set the linger option on the DEALER socket to 0, so that all messages sent on the DEALER socket shall be discarded once the ROUTER socket is closed. Although this works well for TCP connections, it blocks for inproc. Here's a minimal working example:
#include <zmq.h>
#include <windows.h>
int main()
{
void *context = zmq_ctx_new();
void *router = zmq_socket(context, ZMQ_ROUTER);
zmq_bind(router, "inproc://socket");
void *dealer = zmq_socket(context, ZMQ_DEALER);
zmq_connect(dealer, "inproc://socket");
int linger = 0;
zmq_setsockopt(dealer, ZMQ_LINGER, &linger, sizeof(linger));
zmq_close(router);
// sleep for 1 ms
Sleep(1);
// this call blocks
zmq_send(dealer, "message", 7, 0);
zmq_close(dealer);
zmq_ctx_destroy(context);
return 0;
}
Before the DEALER socket can be closed, the zmq_send() call blocks. In this minimal example, I had to add a Sleep(1) call. When this call is omitted, zmq_send() doesn't block. When blocked, the call stack is as follows:
[External Code]
libzmq.dll!zmq::signaler_t::wait(int timeout_) Line 253 C++
libzmq.dll!zmq::mailbox_t::recv(zmq::command_t * cmd_, int timeout_) Line 80 C++
libzmq.dll!zmq::socket_base_t::process_commands(int timeout_, bool throttle_) Line 1023 C++
libzmq.dll!zmq::socket_base_t::send(zmq::msg_t * msg_, int flags_) Line 869 C++
libzmq.dll!s_sendmsg(zmq::socket_base_t * s_, zmq_msg_t * msg_, int flags_) Line 346 C++
libzmq.dll!zmq_send(void * s_, const void * buf_, unsigned __int64 len_, int flags_) Line 371 C++
I'm using Windows 10 x64, libzmq 4.2.1 (tested it with 4.1.6 as well), and Visual Studio 2015. How can I cleanly shut down the DEALER/ROUTER connection? Is this a bug in libzmq?