[zeromq-dev] zmq_poll versus zloop reactor: different semantics - how to resolve?

Michael Haberler mail17 at mah.priv.at
Mon Sep 24 21:00:00 CEST 2012


I have an application where a named pipe, and a sysfs device is monitored. I did the prototype with libzmq - which worked fine - and the switched to czmq, which broke things for me.

the issue is: czmq is too agresssive in shutting down a poll handler if a POLLERR is returned.

Note if you do 'echo value >pipe', poll(2) returns a POLLIN (pipe readable), followed by a POLLER (pipe closed).
When a sysfs entry is notified by the kernel by sysfs_notify(), a poll(2) returns with POLLERR and POLLPRI bits set. (see http://lwn.net/Articles/174660/)
so in both cases, POLLERR doesnt signify anything abnormal.

The zmq version works just fine with a logic like so; similar for the pipe case:

  zmq_pollitem_t items [] = {
	...
        { 0, fd, ZMQ_POLLERR, 0 }
    };
..
    if (items [1].revents & ZMQ_POLLERR) { // sysfs entry was signaled with sysfs_notify()
            lseek(fd, 0, SEEK_SET);
            len = read(fd, buf, sizeof(buf));
       	    ....
    }


Now with czmq, a POLLERR bit returned from poll2() within a zloop() reactor will disable the handler after the first POLLERR (zloop.c:401) meaning only the first pipe reabable/sysfs_notify() event will be handled.

I've found a sledgehammer workaround: in the handler, close the device, deregister poller with zloop_poller_end (), reopen device, re-register with zloop_poller(). The net effect of this is to clear poller->errors so the handler isnt disabled after the first POLLERR.

I dont like it, but am unsure what to do; fiddling with the inner loop of the reactor I dont feel confident about yet.

any suggestions?

- Michael




More information about the zeromq-dev mailing list