PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Saturday, October 22, 2022

[FIXED] How do I cleanly shutdown zeromq DEALER/ROUTER inproc connections

 October 22, 2022     inproc, sockets, zeromq     No comments   

Issue

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?


Solution

Would it be feasable to use ZMQ_DONTWAIT in your

zmq_send()

call and evaluate the errorcode?

Changing your code to

// this call blocks no more
zmq_send(dealer, "message", 7, ZMQ_DONTWAIT);
int ec = zmq_errno();
printf("code: %d\nstring: %s\n", ec, zmq_strerror(ec));

would result in

code: 11

string: Resource temporarily unavailable

Alternatively, can a socket monitor be used to detect the close event and prevent further sending? This does depend on your architecture.



Answered By - x29a
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing