Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZMQ_REQ socket does not report ZMQ_POLLOUT when ZMQ_REQ_RELAXED is set #2824

Closed
rolftimmermans opened this issue Nov 7, 2017 · 4 comments
Closed

Comments

@rolftimmermans
Copy link
Member

rolftimmermans commented Nov 7, 2017

Issue description

When creating a ZMQ_REQ socket with ZMQ_REQ_RELAXED enabled, the ZMQ_EVENTS socket option does not indicate the socket is writable after sending the first message. In spite of that, a call to zmq_send() does in fact succeed without errors (as expected).

Environment

  • libzmq version: 4.4.2
  • OS: macOS High Sierra

Minimal test code

#include <zmq.h>
#include <unistd.h>

int main() {
    void* ctx = zmq_ctx_new();
    void* req = zmq_socket(ctx, ZMQ_REQ);
    void* rep = zmq_socket(ctx, ZMQ_REP);

    int res;
    int events;
    size_t events_len;

    int relaxed = 1;
    res = zmq_setsockopt(req, ZMQ_REQ_RELAXED, &relaxed, sizeof(relaxed));
    assert(res == 0);

    res = zmq_connect(req, "tcp://127.0.0.1:12345");
    assert(res == 0);

    res = zmq_bind(rep, "tcp://127.0.0.1:12345");
    assert(res == 0);

    sleep(1);

    res = zmq_getsockopt(req, ZMQ_EVENTS, &events, &events_len);
    assert(res == 0);
    printf("%i\n", (events & ZMQ_POLLOUT) == ZMQ_POLLOUT);

    res = zmq_send(req, "foo", 3, 0);
    assert(res == 3);

    res = zmq_getsockopt(req, ZMQ_EVENTS, &events, &events_len);
    assert(res == 0);
    printf("%i\n", (events & ZMQ_POLLOUT) == ZMQ_POLLOUT);

    res = zmq_send(req, "bar", 3, 0);
    assert(res == 3);
    return 0
}

What's the actual result?

The output of this program is:

1
0

That is; (events & ZMQ_POLLOUT) == ZMQ_POLLOUT evaluates as true for the first message, but false after sending the second message.

What's the expected result?

My expectation is that the output would be:

1
1

In other words; (events & ZMQ_POLLOUT) == ZMQ_POLLOUT for the REQ socket if ZMQ_REQ_RELAXED is set.

This seems like a problem in https://github.com/zeromq/libzmq/blob/master/src/req.cpp#L216 – I believe the code should check for strictness just like sending does; therefore I think it should be:

if (receiving_reply && strict)
    return false;

Does this make sense? Am I right in expecting that the REQ socket with ZMQ_REQ_RELAXED enabled should be writable according to the ZMQ_EVENTS socket option?

@bluca
Copy link
Member

bluca commented Nov 7, 2017

Yeah I think it makes sense, and your fix should work. Would you please send a PR, including the test for it?

@rolftimmermans
Copy link
Member Author

I would, but I'm struggling to run the tests. Is there any guide?

@rolftimmermans
Copy link
Member Author

rolftimmermans commented Nov 8, 2017

Think I managed to get it working on macOS by running:

sudo sysctl -w kern.maxfiles=64000
sudo sysctl -w kern.maxfilesperproc=64000
sudo launchctl limit maxfiles 64000 64000
ulimit -n 64000
rm -rf tmp && BUILD_TYPE=default ./ci_build.sh 

@bluca
Copy link
Member

bluca commented Nov 8, 2017

That should work although it's for the CI, make check should be all you need

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants