The api is very vague so I want to ask it here, how the zmq_poll works.
Lets say we have this code:
//set timerValue here
1: items[0].socket = server_socket;
2: items[0].events = ZMQ_POLLIN;
3: items[0].fd = timerfd_create(CLOCK_REALTIME, 0);
4:
5: timerfd_settime(items[0].fd, 0, &timerValue, NULL);
6:
7: zmq_poll(items, 1, -1);
8:
9: if(items[0].revents & ZMQ_POLLIN){
10: ...
11: }
And lets say that the timer runs a minute and times out then. If we go through this code, we set a socket and the file descriptor. The api says:
For each zmq_pollitem_t item, zmq_poll() shall examine either the ØMQ socket referenced by socket or the standard socket specified by the file descriptor fd, for the event(s) specified in events. If both socket and fd are set in a single zmq_pollitem_t, the ØMQ socket referenced by socket shall take precedence and the value of fd shall be ignored. http://api.zeromq.org/2-1:zmq-poll
What does it exactly mean if I set the socket and the file descriptor? Does it primarily wait for the socket, that the client send msg and if it does not get any event it waits for the timer?
If we call line 7, does it wait at line 7 as long as the timer is up or it gets an event? Or do I have to implement a while(1) loop to check everytime the if statement in line 9?
In which cases would you need multiple items? (If you want to set multiple timer?)
So basically how does zmq_poll behave with fd and/or socket? Where is the wait process? I thought poll is similiar to interrupt (or wait?). I am a little bit confused with this all.
Most operating systems have a system call to efficiently wait for events on objects. On Linux this system call is poll()
and the objects are file descriptors.
Because ZeroMQ sockets are not file descriptors, you cannot use poll()
with ZeroMQ sockets. That's why there is zmq_poll()
. As an extra bonus, zmq_poll()
allows you to wait for events on ZeroMQ sockets and file descriptors. This is useful for many programs. For example, if you have an interactive program, you want to wait for events on ZeroMQ sockets and keyboard input from standard input, which is a file descriptor.
Regarding your code and your questions:
zmq_poll()
has a timeout argument. There is no need to create a timer yourself..socket
or the .fd
member of zmq_pollitem_t
but not both. Set the other to 0. If you set both, ZeroMQ will ignore the .fd
member.zmq_poll()
your program will block until zmq_poll()
returns. zmq_poll()
returns either when an event occurs on one of the zmq_pollitem_t
s or when the timeout expires.zmq_pollitem_t
s as you need. This depends on your program. For example, a server might handle multiple connections and you create a zmq_pollitem_t
for each connection.The following example code waits for a ZeroMQ socket and a file descriptor.
void wait_for_socket_and_fd(void* sock, int fd, long timeout)
{
// wait for two objects
zmq_pollitem_t items[2];
// wait for ZeroMQ socket...
items[0].socket = sock;
items[0].fd = 0;
items[0].events = ZMQ_POLLIN;
// ...and wait for fd
items[1].socket = NULL;
items[1].fd = fd;
items[1].events = ZMQ_POLLIN;
// block until event occurs or timeout expires
int ret = zmq_poll(items, sizeof(items) / sizeof(items[0]), timeout);
if (ret > 0)
{
// event occurred
if (items[0].revents != 0)
{
// event occurred on sock, process it
}
if (items[1].revents != 0)
{
// event occurred on fd, process it
}
}
else if (ret == 0)
{
// timeout expired, do something
}
else
{
// error occurred, handle it
}
}