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

Reply via email to