[zeromq-dev] missing events ZMQ_FD / ZMQ_EVENTS

Gerhard Lipp gelipp at googlemail.com
Fri Apr 27 13:10:37 CEST 2012


On Fri, Apr 27, 2012 at 11:57 AM, Paul Colomiets <paul at colomiets.name> wrote:
> Hi Gerhard,
>
> On Fri, Apr 27, 2012 at 12:37 PM, Gerhard Lipp <gelipp at googlemail.com> wrote:
>> I don't think it is a docu thing.
>>
>> What the docu says  (and what the source looks like)
>> zmq_getsockopt(ZMQ_FD) returns a fd (the mailbox's), which becomes
>> readable, whenever the corresponding socket might have become readable
>> and/or writeable for operation with the NOBLOCK option. To check which
>> of these conditions are true, you have to use
>> zmq_getsockopt(ZMQ_EVENTS) and check for ZMQ_POLLIN / ZMQ_POLLOUT
>> respectively.
>>
>
> This is totally true. The but it's silent on some things.
>
>> If this is true, users should ONLY select/poll for the read event,
>> e.g. using libev EV_READ, regardless if the user wants to
>> zmq_recv(ZMQ_NOBLOCK) or zmq_send(ZMQ_NOBLOCK).
>
> Yes. Only for EV_READ. I don't know how lua works with
> libev so I've made an ill advice, sorry. (see below)
>
>>
>> I guess the "solution/workaround" of the example (using ev.READ +
>> ev.WRITE) does not work reliable and under all circumstances, but just
>> in this primitive scenario.
>>
>
> Adding ev.WRITE helps only because socket is *always* ready
> for writing. So you are in a tight loop actually.

Damn it! Thanks for pointing that out! That's way the device is so
damn 'slow'.... stupid.

The real missing
> part of documentation is here.

>
> https://github.com/zeromq/libzmq/pull/328/files

Ok, so i must always check if there are more events to process before
returning from the io handler (frankly I don't understand the
explanation). A short test still shows the lock explained earlier:

------
-- x.lua
-------

local zmq = require'zmq'
local ev = require'ev'
local c = zmq.init(1)
local xreq = c:socket(zmq.XREQ)
xreq:bind('tcp://127.0.0.1:13333')
local xrep = c:socket(zmq.XREP)
xrep:bind('tcp://127.0.0.1:13334')

local is_readable =
   function(sock)
      local events = sock:getopt(zmq.EVENTS)
      return events == zmq.POLLIN or events == (zmq.POLLIN + zmq.POLLOUT)
   end

local forward_io =
   function(src,dst)
      return ev.IO.new(
         function(loop,io) -- called whenever src:getopt(zmq.FD)
becomes readable
            while is_readable(src) do
               repeat
                  local data = assert(src:recv(zmq.NOBLOCK)) -- this
will assert that there is data
                  local more = src:getopt(zmq.RCVMORE) > 0
                  dst:send(data,more and zmq.SNDMORE or 0)
               until not more
            end
         end,
         src:getopt(zmq.FD),
         ev.READ
      )
   end
local xrep_io = forward_io(xrep,xreq)
local xreq_io = forward_io(xreq,xrep)
xreq_io:start(ev.Loop.default)
xrep_io:start(ev.Loop.default)
ev.Loop.default:loop()



>
> --
> Paul
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev



More information about the zeromq-dev mailing list