]> Dogcows Code - chaz/yoink/blob - src/moof/runloop.cc
further implementing runloop support
[chaz/yoink] / src / moof / runloop.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include "config.h"
13
14 #include <algorithm>
15
16 #include "hash.hh"
17 #include "log.hh"
18 #include "runloop.hh"
19 #include "timer.hh"
20
21
22 namespace moof {
23
24
25 enum registry_action
26 {
27 lookup,
28 set
29 };
30
31 static uint32_t call_registry(runloop*& runloop, registry_action action)
32 {
33 #if ENABLE_THREADS
34 typedef stlplus::hash<uint32_t,moof::runloop*,hash_function> table_t;
35 static table_t table;
36
37 uint32_t thread_id = thread::current_identifier();
38
39 MOOF_DECLARE_STATIC_MUTEX(table_mutex);
40 MOOF_MUTEX_LOCK(table_mutex);
41
42 switch (action)
43 {
44 case set:
45 {
46 log_info("registering runloop", runloop, "for thread", thread_id);
47 if (runloop) table[thread_id] = runloop;
48 else table.erase(thread_id);
49 break;
50 }
51
52 case lookup:
53 {
54 table_t::iterator it = table.find(thread_id);
55 if (it != table.end()) runloop = (*it).second;
56 else log_warning("runloop is not in registry for thread", thread_id);
57 break;
58 }
59 }
60
61 return thread_id;
62 #else
63 return thread::current_identifier();
64 #endif
65 }
66
67 bool comp(timer* a, timer* b)
68 {
69 return a->expiration() < b->expiration();
70 }
71
72 int runloop::run()
73 {
74 #if ENABLE_THREADS
75 runloop* runloop = this;
76 thread_id_ = call_registry(runloop, set);
77 #endif
78
79 stop_ = false;
80 while (!stop_)
81 {
82 log_debug("------------------------------------");
83 scalar next_event = SCALAR(0.0);
84 {
85 MOOF_MUTEX_LOCK(timers_mutex_);
86
87 for (timers_it_ = timers_.begin();
88 timers_it_ != timers_.end();
89 ++timers_it_)
90 {
91 (*timers_it_)->fire_if_expired();
92 }
93
94 std::sort(timers_.begin(), timers_.end(), comp);
95 next_event = timers_[0]->expiration();
96
97 //for (timers_it_ = timers_.begin();
98 //timers_it_ != timers_.end();
99 //++timers_it_)
100 //{
101 //scalar absolute = (*timers_it_)->fire_if_expired();
102 //if (next_event == SCALAR(0.0) ||
103 //(absolute != SCALAR(0.0) && absolute < next_event))
104 //{
105 //next_event = absolute;
106 //}
107 //}
108 }
109 timer::sleep(next_event, timer::absolute);
110 }
111
112 return code_;
113 }
114
115
116 runloop::~runloop()
117 {
118 runloop* runloop = 0;
119 call_registry(runloop, set);
120 }
121
122
123 void runloop::stop(int code)
124 {
125 code_ = code;
126 stop_ = true;
127 }
128
129
130 runloop* runloop::current()
131 {
132 runloop* runloop;
133 call_registry(runloop, lookup);
134 return runloop;
135 }
136
137
138 void runloop::add_timer(timer& timer)
139 {
140 #if ENABLE_THREADS
141 if (thread_id_ != thread::current_identifier())
142 {
143 MOOF_MUTEX_LOCK(timers_mutex_);
144 timers_.push_back(&timer);
145 timers_it_ = timers_.end();
146 }
147 else
148 #endif
149 {
150 timers_.push_back(&timer);
151 timers_it_ = timers_.end();
152 }
153 }
154
155 void runloop::remove_timer(timer& timer)
156 {
157 #if ENABLE_THREADS
158 if (thread_id_ != thread::current_identifier())
159 {
160 MOOF_MUTEX_LOCK(timers_mutex_);
161 timers_.erase(std::find(timers_.begin(), timers_.end(), &timer));
162 timers_it_ = timers_.end();
163 }
164 else
165 #endif
166 {
167 timers_.erase(std::find(timers_.begin(), timers_.end(), &timer));
168 timers_it_ = timers_.end();
169 }
170 }
171
172
173 } // namespace moof
174
This page took 0.036386 seconds and 4 git commands to generate.