-/*] 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 <algorithm>
#include "hash.hh"
+#include "log.hh"
#include "runloop.hh"
#include "timer.hh"
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<uint32_t,moof::runloop*,hash_function> 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();
}
}