X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Frunloop.cc;h=f8e4ccfd08596ed6a91e6c1c6109f26854d6ac3a;hp=db598145f17fbb7f14e40d6b02713109cd67cd94;hb=574af38ed616d1adfa5e6ce35f67cda1f707f89d;hpb=d6990468d297a6cbee98e4d0d33ab37e1b2352c9 diff --git a/src/moof/runloop.cc b/src/moof/runloop.cc index db59814..f8e4ccf 100644 --- a/src/moof/runloop.cc +++ b/src/moof/runloop.cc @@ -1,15 +1,20 @@ -/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +/*] Copyright (c) 2009-2011, Charles McGarvey [***************************** **] All rights reserved. * -* vi:ts=4 sw=4 tw=75 -* * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * -**************************************************************************/ +*****************************************************************************/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include #include "hash.hh" +#include "log.hh" #include "runloop.hh" #include "timer.hh" @@ -17,128 +22,81 @@ namespace moof { -enum registry_action +bool comp(timer* a, timer* b) { - lookup, - set -}; + return a->expiration() < b->expiration(); +} -static uint32_t call_registry(runloop*& runloop, registry_action action) -{ - typedef stlplus::hash table_t; - static table_t table; - uint32_t thread_id = thread::current_identifier(); +int runloop::run_once() +{ +#if ENABLE_THREADS + thread_id_ = thread::current_identifier(); +#endif - static MOOF_DECLARE_MUTEX(table_mutex); - MOOF_MUTEX_LOCK(table_mutex); + //log_debug("------------------------------------"); + int expired = 0; + MOOF_MUTEX_LOCK(timers_mutex_); - switch (action) + std::sort(timers_.begin(), timers_.end(), comp); + for (timers_it_ = timers_.begin(); + timers_it_ != timers_.end(); ++timers_it_) { - case set: - { - if (runloop) table[thread_id] = runloop; - else table.erase(thread_id); - break; - } - - case lookup: - { - table_t::iterator it = table.find(thread_id); - if (it != table.end()) runloop = (*it).second; - break; - } + if ((*timers_it_)->fire_if_expired()) ++expired; } - - return thread_id; + return expired; } - int runloop::run() { -#if ENABLE_THREADS - runloop* runloop = this; - thread_id_ = call_registry(runloop, set); -#endif - stop_ = false; while (!stop_) { - scalar next_event = SCALAR(0.0); - { - MOOF_MUTEX_LOCK(timers_mutex_); - - for (timers_it_ = timers_.begin(); - timers_it_ != timers_.end(); - ++timers_it_) - { - scalar absolute = (*timers_it_)->fire_if_expired(); - if (next_event == SCALAR(0.0) || - (absolute != SCALAR(0.0) && absolute < next_event)) - { - next_event = absolute; - } - } - } - timer::sleep(next_event, timer::absolute); + if (run_once() == 0);//timer::sleep(SCALAR(0.0)); + // TODO: maybe sleep(0.0001) will actually return sooner than + // sleep(0)... if the kernel interprets sleep(0) as we don't need + // to process for an arbitrarily long timespan while specifying a + // value lets the kernel know when we need control back... } - return code_; } - -runloop::~runloop() -{ - runloop* runloop = 0; - call_registry(runloop, set); -} - - void runloop::stop(int code) { code_ = code; stop_ = true; } - -runloop* runloop::current() -{ - runloop* runloop; - call_registry(runloop, lookup); - return runloop; -} - - -void runloop::add_timer(timer* timer) +void runloop::add_timer(timer& timer) { #if ENABLE_THREADS if (thread_id_ != thread::current_identifier()) { MOOF_MUTEX_LOCK(timers_mutex_); - timers_.insert(timer); + timers_.push_back(&timer); timers_it_ = timers_.end(); } else #endif { - timers_.insert(timer); + timers_.push_back(&timer); timers_it_ = timers_.end(); } } -void runloop::remove_timer(timer* timer) +void runloop::remove_timer(timer& timer) { #if ENABLE_THREADS if (thread_id_ != thread::current_identifier()) { MOOF_MUTEX_LOCK(timers_mutex_); - timers_.erase(timer); + timers_.erase(std::find(timers_.begin(), timers_.end(), &timer)); timers_it_ = timers_.end(); } else #endif { - timers_.erase(timer); + timers_.erase(std::find(timers_.begin(), timers_.end(), &timer)); timers_it_ = timers_.end(); } }