[zeromq-dev] ZMQ_POLLIN received on WRITE event

Goswin von Brederlow goswin-v-b at web.de
Thu Sep 25 13:54:32 CEST 2014

On Thu, Sep 25, 2014 at 11:09:15AM +0200, Dorvin wrote:
> Thank you for your replies so far. I'll clarify if it does matter that 
> I'm using Windows and libzmq 4.0.4.
> W dniu 2014-09-25 04:38, Goswin von Brederlow pisze:
> >the ØMQ library
> >      shall signal any pending events on the socket in an edge-triggered
> >      fashion by making the file descriptor become ready for reading.
> This is exactly what bothers me. According to documentation I'm supposed 
> to get most socket events when FD gets ready for reading.
> But when I do:
> sel_ret = select(sub_fd + 1, &sub_set, NULL, NULL, &time );
> if (sel_ret == 1)
> {
>      zmq_getsockopt(subscriber, ZMQ_EVENTS, &zevents, &zevents_len);
>      if(zevents & ZMQ_POLLIN)
>      {
>          //retrieve and do something with message
>      }
> }
> I receive only some or none messages at all. You may see it in testcase.
> For now I found 3 options to work this out:
> 1. Use zmq_poll() periodically - this seems to get read and write 
> notifications at the same time and therefore not lose events. This does 
> not look like event-driven way of doing things, though.
> 2. Use getsockopt with ZMQ_EVENTS after each send or receive - this is 
> like small version of zmq_poll invoked almost constantly.
> 3. Keeping write notifier active all time which is not a good idea 
> because it fires on every pass of event loop. In first reply I already 
> was discouraged from this option.
> If you would be so kind I would ask you to execute my code, see results 
> and tell me if it's expected behavior (some kind of optimization or 
> something), I miss something in how 0mq sockets should work, or if I 
> should file bug report.
> You may remove line "if (occurences > 0) {break;};" to see that what I 
> describe is not single event but it repeats.
> With regards,
> Jarek

It might help if you would post a testcase that:

a) actualy compiles
b) doesn't involve undefined behaviour:

       (ii)   select()  may  update  the timeout argument to indicate how much
              time was left.  pselect() does not change this argument.

       On  Linux,  select() modifies timeout to reflect the amount of time not
       slept; most other implementations do not do this.   (POSIX.1-2001  per-
       mits either behavior.)  This causes problems both when Linux code which
       reads timeout is ported to other operating systems, and  when  code  is
       ported  to Linux that reuses a struct timeval for multiple select()s in
       a loop without reinitializing it.  Consider  timeout  to  be  undefined
       after select() returns.

c) gives an error where the problem occurs or describe what the
expected outcome should be and what it acutally is

All I see is that you use select with 0 timeout, which makes the
select basically pointless. You also wrongly select the FD for
writability (which is always possible, so a NOP) and then "break" when
a message was received. Since messages arrive asynchronously you
eventually hit the case where a message gets received just at that
time. Nothing wrong there.


More information about the zeromq-dev mailing list