summaryrefslogtreecommitdiff
path: root/src/poller_base.cpp
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2010-09-26 21:42:23 +0200
committerMartin Sustrik <sustrik@250bpm.com>2010-09-26 21:42:23 +0200
commit238640a526c419392bf2df95de196db89ea6eb73 (patch)
tree8434dfc49117739f1d344a3d96a4957f6206d9d0 /src/poller_base.cpp
parent8d7bf6684cbb9625ec7c963b8867e2411b49eb57 (diff)
timers properly implemented
Diffstat (limited to 'src/poller_base.cpp')
-rw-r--r--src/poller_base.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/poller_base.cpp b/src/poller_base.cpp
index f1de7e9..d55692a 100644
--- a/src/poller_base.cpp
+++ b/src/poller_base.cpp
@@ -18,6 +18,7 @@
*/
#include "poller_base.hpp"
+#include "i_poll_events.hpp"
#include "err.hpp"
zmq::poller_base_t::poller_base_t ()
@@ -26,7 +27,7 @@ zmq::poller_base_t::poller_base_t ()
zmq::poller_base_t::~poller_base_t ()
{
- // Make sure there are no fds registered on shutdown.
+ // Make sure there is no more load on the shutdown.
zmq_assert (get_load () == 0);
}
@@ -42,3 +43,52 @@ void zmq::poller_base_t::adjust_load (int amount_)
else if (amount_ < 0)
load.sub (-amount_);
}
+
+void zmq::poller_base_t::add_timer (int timeout_, i_poll_events *sink_, int id_)
+{
+ uint64_t expiration = clock.now_ms () + timeout_;
+ timer_info_t info = {sink_, id_};
+ timers.insert (std::make_pair (expiration, info));
+}
+
+void zmq::poller_base_t::cancel_timer (i_poll_events *sink_, int id_)
+{
+ // Complexity of this operation is O(n). We assume it is rarely used.
+ for (timers_t::iterator it = timers.begin (); it != timers.end (); it++)
+ if (it->second.sink == sink_ && it->second.id == id_) {
+ timers.erase (it);
+ return;
+ }
+
+ // Timer not found.
+ zmq_assert (false);
+}
+
+uint64_t zmq::poller_base_t::execute_timers ()
+{
+ // Get the current time.
+ uint64_t current = clock.now_ms ();
+
+ // Execute the timers that are already due.
+ timers_t::iterator it = timers.begin ();
+ while (it != timers.end ()) {
+
+ // If we have to wait to execute the item, same will be true about
+ // all the following items (multimap is sorted). Thus we can stop
+ // checking the subsequent timers and return the time to wait for
+ // the next timer (at least 1ms).
+ if (it->first > current)
+ return it->first - current;
+
+ // Trigger the timer.
+ it->second.sink->timer_event (it->second.id);
+
+ // Remove it from the list of active timers.
+ timers_t::iterator o = it;
+ ++it;
+ timers.erase (o);
+ }
+
+ // There are no more timers.
+ return 0;
+}