-/*] 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>
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)
+int runloop::run_once()
{
#if ENABLE_THREADS
- typedef stlplus::hash<uint32_t,moof::runloop*,hash_function> table_t;
- static table_t table;
-
- uint32_t thread_id = thread::current_identifier();
+ thread_id_ = thread::current_identifier();
+#endif
- MOOF_DECLARE_STATIC_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:
- {
- log_info("registering runloop", runloop, "for thread", thread_id);
- 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;
- else log_warning("runloop is not in registry for thread", thread_id);
- break;
- }
+ if ((*timers_it_)->fire_if_expired()) ++expired;
}
-
- return thread_id;
-#else
- return thread::current_identifier();
-#endif
-}
-
-bool comp(timer* a, timer* b)
-{
- return a->expiration() < b->expiration();
+ return expired;
}
int runloop::run()
{
-#if ENABLE_THREADS
- runloop* runloop = this;
- thread_id_ = call_registry(runloop, set);
-#endif
-
stop_ = false;
while (!stop_)
{
- log_debug("------------------------------------");
- scalar next_event = SCALAR(0.0);
- {
- MOOF_MUTEX_LOCK(timers_mutex_);
-
- for (timers_it_ = timers_.begin();
- timers_it_ != timers_.end();
- ++timers_it_)
- {
- (*timers_it_)->fire_if_expired();
- }
-
- std::sort(timers_.begin(), timers_.end(), comp);
- next_event = timers_[0]->expiration();
-
- //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)
{
#if ENABLE_THREADS