Hi all,
Here's a patch to master that should prevent zmq_poll exiting when
specified timeout is not yet reached.
Testing and reporting problems is welcome!
Martin
>From 9d1306d6bbee66ad2285d164a37df2f6d1dde741 Mon Sep 17 00:00:00 2001
From: Martin Sustrik <sust...@250bpm.com>
Date: Wed, 13 Oct 2010 13:58:52 +0200
Subject: [PATCH] Precise timeouts implemented for zmq_poll.
Signed-off-by: Martin Sustrik <sust...@250bpm.com>
---
src/zmq.cpp | 37 ++++++++++++++++++++++++++++---------
1 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/src/zmq.cpp b/src/zmq.cpp
index dad4367..14df217 100644
--- a/src/zmq.cpp
+++ b/src/zmq.cpp
@@ -384,6 +384,10 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
return -1;
}
+ zmq::clock_t clock;
+ uint64_t now = 0;
+ uint64_t end = 0;
+
pollfd *pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd));
zmq_assert (pollfds);
@@ -413,16 +417,21 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
bool first_pass = true;
int nevents = 0;
- if (timeout_ >= 0)
- timeout_ /= 1000;
- else
- timeout_ = -1;
while (true) {
+ // Compute the timeout for the subsequent poll.
+ int timeout;
+ if (first_pass)
+ timeout = 0;
+ else if (timeout < 0)
+ timeout = -1;
+ else
+ timeout = end - now;
+
// Wait for events.
while (true) {
- int rc = poll (pollfds, nitems_, first_pass ? 0 : timeout_);
+ int rc = poll (pollfds, nitems_, timeout);
if (rc == -1 && errno == EINTR) {
free (pollfds);
return -1;
@@ -472,6 +481,14 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
// timeout), do at least the second pass so that we wait.
if (first_pass && nevents == 0 && timeout_ != 0) {
first_pass = false;
+
+ // In case of finite timeout get a timestamp of when the polling
+ // have begun. (We assume that first pass have taken negligible
+ // time). Also compute the time when the polling should time out.
+ if (timeout_ > 0) {
+ now = clock.now_ms ();
+ end = now + (timeout_ / 1000);
+ }
continue;
}
@@ -480,10 +497,12 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
if (timeout_ == -1 && nevents == 0)
continue;
- // TODO: if nevents is zero recompute timeout and loop
- // if it is not yet reached.
-
- break;
+ // In case of finite timeout find out whether it have already elapsed.
+ if (timeout_ > 0) {
+ now = clock.now_ms ();
+ if (now >= end)
+ break;
+ }
}
free (pollfds);
--
1.7.0.4
_______________________________________________
zeromq-dev mailing list
zeromq-dev@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev