[zeromq-dev] Epolling on FD doesn't work for 2.1.11
Andrzej K. Haczewski
ahaczewski at gmail.com
Fri Mar 23 11:31:37 CET 2012
2012/3/22 Robert G. Jakabosky <bobby at sharedrealm.com>:
> zmq sockets are alway level-triggered. Your code should call
> zmq_send/zmq_recv until it returns EAGAIN, then register the FD for read
> events with your event loop. Your code also needs to alway pass the
> ZMQ_NOBLOCK flag to zmq_send/zmq_recv.
>
> For an lib-ev event loop use an idle watcher to call zmq_recv when it is not
> block. Once zmq_recv returns EAGAIN, stop the idle watcher and start an io
> watcher for read events. The ev_io callback needs to get the value of
> ZMQ_EVENTS with zmq_getsockopt(), then check the events value for ZMQ_POLLIN.
> As soon as ZMQ_EVENTS has ZMQ_POLLIN stop the io watcher and start the idle
> watcher again.
>
> Basically if the zmq socket is readable, your code must keep calling
> zmq_recv() until it returns EAGAIN without waiting for another IO read event
> from the event loop.
>
> I have written an example [1] in Lua that reads from a zmq SUB socket using
> the lib-ev event loop.
>
> Also there is client [2] and server [3] example (using REQ/REP sockets) that
> can use either lib-ev [4] or epoll [5] event loops.
>
> I hope that helps.
>
> 1. https://github.com/Neopallium/lua-
> zmq/blob/master/examples/subscriber_ev.lua
> 2. https://github.com/Neopallium/lua-zmq/blob/master/examples/client_poll.lua
> 3. https://github.com/Neopallium/lua-zmq/blob/master/examples/server_poll.lua
> 4. https://github.com/Neopallium/lua-zmq/blob/master/examples/poller/ev.lua
> 5. https://github.com/Neopallium/lua-zmq/blob/master/examples/poller/epoll.lua
Thank you so much for your assistance. I'm refactoring my code to
include the scheme you've proposed.
There is one thing that bothers me though: why does the scheme I used
works for ZeroMQ 3.1.0 and CrossroadsIO, as I tired both and they work
with registering FD right away with no recv() calls in between
connect() and epoll(), and it doesn't work for ZeroMQ 2.1.
Also, I wonder if there might be a race in proposed approach, between
getting EAGAIN and starting to watch FD, since it might be quite a lot
of time between I process all the pending tasks I have on my queue
(which that idle recv() task will belong to) and actually entering
epoll. Or does ZeroMQ 2.1 guarantee that after throwing EAGAIN at user
it will never clear pending event from socket before user has a chance
of epolling on that socket's FD?
Best regards,
Andrzej Haczewski
More information about the zeromq-dev
mailing list