… | |
… | |
105 | { |
105 | { |
106 | unreg (w, cw); |
106 | unreg (w, cw); |
107 | } |
107 | } |
108 | #endif |
108 | #endif |
109 | |
109 | |
|
|
110 | #if IOM_IDLE |
|
|
111 | idle_watcher::~idle_watcher () |
|
|
112 | { |
|
|
113 | if (iom_valid) |
|
|
114 | iom.unreg (this); |
|
|
115 | } |
|
|
116 | |
|
|
117 | void io_manager::reg (idle_watcher *w) |
|
|
118 | { |
|
|
119 | reg (w, iw); |
|
|
120 | } |
|
|
121 | |
|
|
122 | void io_manager::unreg (idle_watcher *w) |
|
|
123 | { |
|
|
124 | unreg (w, iw); |
|
|
125 | } |
|
|
126 | #endif |
|
|
127 | |
110 | #if IOM_TIME |
128 | #if IOM_TIME |
111 | inline void set_now (void) |
129 | inline void set_now (void) |
112 | { |
130 | { |
113 | struct timeval tv; |
131 | struct timeval tv; |
114 | |
132 | |
… | |
… | |
124 | set_now (); |
142 | set_now (); |
125 | #endif |
143 | #endif |
126 | |
144 | |
127 | for (;;) |
145 | for (;;) |
128 | { |
146 | { |
|
|
147 | struct timeval *to = 0; |
|
|
148 | struct timeval tval; |
|
|
149 | |
|
|
150 | #if IOM_IDLE |
|
|
151 | if (iw.size ()) |
|
|
152 | { |
|
|
153 | tval.tv_sec = 0; |
|
|
154 | tval.tv_usec = 0; |
|
|
155 | to = &tval; |
|
|
156 | } |
|
|
157 | else |
|
|
158 | #endif |
|
|
159 | { |
|
|
160 | #if IOM_TIME |
|
|
161 | time_watcher *w; |
|
|
162 | |
|
|
163 | for (;tw.size ();) |
|
|
164 | { |
|
|
165 | w = tw[0]; |
|
|
166 | |
|
|
167 | for (time_watcher **i = tw.begin (); i < tw.end (); ++i) |
|
|
168 | if ((*i)->at < w->at) |
|
|
169 | w = *i; |
|
|
170 | |
|
|
171 | if (w->at > NOW) |
|
|
172 | { |
|
|
173 | double diff = w->at - NOW; |
|
|
174 | tval.tv_sec = (int)diff; |
|
|
175 | tval.tv_usec = (int)((diff - tval.tv_sec) * 1000000); |
|
|
176 | to = &tval; |
|
|
177 | break; |
|
|
178 | } |
|
|
179 | else if (w->at >= 0) |
|
|
180 | w->call (*w); |
|
|
181 | else |
|
|
182 | unreg (w); |
|
|
183 | } |
|
|
184 | #endif |
|
|
185 | } |
|
|
186 | |
129 | #if IOM_CHECK |
187 | #if IOM_CHECK |
130 | for (int i = 0; i < cw.size (); ++i) |
188 | for (int i = 0; i < cw.size (); ++i) |
131 | cw[i]->call (*cw[i]); |
189 | cw[i]->call (*cw[i]); |
132 | #endif |
|
|
133 | |
|
|
134 | #if IOM_TIME |
|
|
135 | time_watcher *w; |
|
|
136 | |
|
|
137 | for (;;) |
|
|
138 | { |
|
|
139 | w = tw[0]; |
|
|
140 | |
|
|
141 | for (time_watcher **i = tw.begin (); i < tw.end (); ++i) |
|
|
142 | if ((*i)->at < w->at) |
|
|
143 | w = *i; |
|
|
144 | |
|
|
145 | if (w->at > NOW) |
|
|
146 | break; |
|
|
147 | |
|
|
148 | // call it |
|
|
149 | w->call (*w); |
|
|
150 | |
|
|
151 | if (w->at < 0) |
|
|
152 | unreg (w); |
|
|
153 | } |
|
|
154 | |
|
|
155 | double diff = w->at - NOW; |
|
|
156 | struct timeval to; |
|
|
157 | to.tv_sec = (int)diff; |
|
|
158 | to.tv_usec = (int)((diff - to.tv_sec) * 1000000); |
|
|
159 | #endif |
190 | #endif |
160 | |
191 | |
161 | #if IOM_IO |
192 | #if IOM_IO |
162 | fd_set rfd, wfd; |
193 | fd_set rfd, wfd; |
163 | |
194 | |
… | |
… | |
169 | for (io_watcher **w = iow.begin (); w < iow.end (); ++w) |
200 | for (io_watcher **w = iow.begin (); w < iow.end (); ++w) |
170 | { |
201 | { |
171 | if ((*w)->events & EVENT_READ ) FD_SET ((*w)->fd, &rfd); |
202 | if ((*w)->events & EVENT_READ ) FD_SET ((*w)->fd, &rfd); |
172 | if ((*w)->events & EVENT_WRITE) FD_SET ((*w)->fd, &wfd); |
203 | if ((*w)->events & EVENT_WRITE) FD_SET ((*w)->fd, &wfd); |
173 | |
204 | |
174 | if ((*w)->fd > fds) fds = (*w)->fd; |
205 | if ((*w)->fd >= fds) fds = (*w)->fd + 1; |
175 | } |
206 | } |
176 | |
207 | |
|
|
208 | if (!to && !fds) |
|
|
209 | break; // no events |
|
|
210 | |
|
|
211 | fds = select (fds, &rfd, &wfd, 0, to); |
177 | # if IOM_TIME |
212 | # if IOM_TIME |
178 | fds = select (fds + 1, &rfd, &wfd, 0, &to); |
|
|
179 | set_now (); |
213 | set_now (); |
180 | # else |
|
|
181 | fds = select (fds + 1, &rfd, &wfd, 0, 0); |
|
|
182 | # endif |
214 | # endif |
183 | |
215 | |
184 | if (fds > 0) |
216 | if (fds > 0) |
185 | for (int i = 0; i < iow.size (); ++i) |
217 | for (int i = 0; i < iow.size (); ++i) |
186 | { |
218 | { |
… | |
… | |
192 | if (!FD_ISSET (w->fd, &wfd)) revents &= ~EVENT_WRITE; |
224 | if (!FD_ISSET (w->fd, &wfd)) revents &= ~EVENT_WRITE; |
193 | |
225 | |
194 | if (revents) |
226 | if (revents) |
195 | w->call (*w, revents); |
227 | w->call (*w, revents); |
196 | } |
228 | } |
197 | } |
229 | #if IOM_IDLE |
|
|
230 | else if (iw.size ()) |
|
|
231 | for (int i = 0; i < iw.size (); ++i) |
|
|
232 | iw[i]->call (*iw[i]); |
|
|
233 | #endif |
|
|
234 | |
198 | #elif IOM_TIME |
235 | #elif IOM_TIME |
|
|
236 | if (!to) |
|
|
237 | break; |
|
|
238 | |
199 | select (0, 0, 0, 0, &to); |
239 | select (0, 0, 0, 0, &to); |
200 | set_now (); |
240 | set_now (); |
|
|
241 | #else |
|
|
242 | break; |
201 | #endif |
243 | #endif |
202 | } |
244 | } |
203 | |
|
|
204 | void io_manager::idle_cb (time_watcher &w) |
|
|
205 | { |
|
|
206 | w.at = NOW + 1000000000; |
|
|
207 | } |
245 | } |
208 | |
246 | |
209 | io_manager::io_manager () |
247 | io_manager::io_manager () |
210 | { |
248 | { |
|
|
249 | #if IOM_TIME |
211 | set_now (); |
250 | set_now (); |
|
|
251 | #endif |
212 | |
252 | |
213 | iom_valid = true; |
253 | iom_valid = true; |
214 | |
|
|
215 | #if IOM_TIME |
|
|
216 | idle = new time_watcher (this, &io_manager::idle_cb); |
|
|
217 | idle->start (0); |
|
|
218 | #endif |
|
|
219 | } |
254 | } |
220 | |
255 | |
221 | io_manager::~io_manager () |
256 | io_manager::~io_manager () |
222 | { |
257 | { |
223 | iom_valid = false; |
258 | iom_valid = false; |