X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Frunloop.cc;fp=src%2Fmoof%2Frunloop.cc;h=db598145f17fbb7f14e40d6b02713109cd67cd94;hp=0000000000000000000000000000000000000000;hb=d6990468d297a6cbee98e4d0d33ab37e1b2352c9;hpb=1d4aa0d34b0410c7bc60a24bad7abb55eacc850a diff --git a/src/moof/runloop.cc b/src/moof/runloop.cc new file mode 100644 index 0000000..db59814 --- /dev/null +++ b/src/moof/runloop.cc @@ -0,0 +1,148 @@ + +/*] Copyright (c) 2009-2010, 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. +* +**************************************************************************/ + +#include "hash.hh" +#include "runloop.hh" +#include "timer.hh" + + +namespace moof { + + +enum registry_action +{ + lookup, + set +}; + +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(); + + static MOOF_DECLARE_MUTEX(table_mutex); + MOOF_MUTEX_LOCK(table_mutex); + + switch (action) + { + 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; + } + } + + return thread_id; +} + + +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); + } + + 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) +{ +#if ENABLE_THREADS + if (thread_id_ != thread::current_identifier()) + { + MOOF_MUTEX_LOCK(timers_mutex_); + timers_.insert(timer); + timers_it_ = timers_.end(); + } + else +#endif + { + timers_.insert(timer); + timers_it_ = timers_.end(); + } +} + +void runloop::remove_timer(timer* timer) +{ +#if ENABLE_THREADS + if (thread_id_ != thread::current_identifier()) + { + MOOF_MUTEX_LOCK(timers_mutex_); + timers_.erase(timer); + timers_it_ = timers_.end(); + } + else +#endif + { + timers_.erase(timer); + timers_it_ = timers_.end(); + } +} + + +} // namespace moof +