From 238640a526c419392bf2df95de196db89ea6eb73 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Sun, 26 Sep 2010 21:42:23 +0200 Subject: timers properly implemented --- src/poller_base.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src/poller_base.cpp') 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; +} -- cgit v1.2.3