1 | /* |
1 | /* |
2 | iom.C -- generic I/O multiplexor |
2 | iom.C -- generic I/O multiplexer |
3 | Copyright (C) 2003, 2004 Marc Lehmann <pcg@goof.com> |
3 | Copyright (C) 2003, 2004 Marc Lehmann <pcg@goof.com> |
4 | |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; either version 2 of the License, or |
7 | the Free Software Foundation; either version 2 of the License, or |
… | |
… | |
152 | { |
152 | { |
153 | init::required (); |
153 | init::required (); |
154 | |
154 | |
155 | if (!w.active) |
155 | if (!w.active) |
156 | { |
156 | { |
157 | #if IOM_CHECK |
|
|
158 | queue.activity = true; |
|
|
159 | #endif |
|
|
160 | queue.push_back (&w); |
157 | queue.push_back (&w); |
161 | w.active = queue.size (); |
158 | w.active = queue.size (); |
162 | } |
159 | } |
163 | } |
160 | } |
164 | |
161 | |
… | |
… | |
273 | set_now (); |
270 | set_now (); |
274 | #endif |
271 | #endif |
275 | |
272 | |
276 | for (;;) |
273 | for (;;) |
277 | { |
274 | { |
|
|
275 | |
|
|
276 | #if IOM_TIME |
|
|
277 | // call pending time watchers |
|
|
278 | { |
|
|
279 | bool activity; |
|
|
280 | |
|
|
281 | do |
|
|
282 | { |
|
|
283 | activity = false; |
|
|
284 | |
|
|
285 | for (int i = tw.size (); i--; ) |
|
|
286 | if (!tw[i]) |
|
|
287 | tw.erase_unordered (i); |
|
|
288 | else if (tw[i]->at <= NOW) |
|
|
289 | { |
|
|
290 | time_watcher &w = *tw[i]; |
|
|
291 | |
|
|
292 | unreg (w); |
|
|
293 | w.call (w); |
|
|
294 | |
|
|
295 | activity = true; |
|
|
296 | } |
|
|
297 | } |
|
|
298 | while (activity); |
|
|
299 | } |
|
|
300 | #endif |
|
|
301 | |
|
|
302 | #if IOM_CHECK |
|
|
303 | // call all check watchers |
|
|
304 | for (int i = cw.size (); i--; ) |
|
|
305 | if (!cw[i]) |
|
|
306 | cw.erase_unordered (i); |
|
|
307 | else |
|
|
308 | cw[i]->call (*cw[i]); |
|
|
309 | #endif |
|
|
310 | |
278 | struct TIMEVAL *to = 0; |
311 | struct TIMEVAL *to = 0; |
279 | struct TIMEVAL tval; |
312 | struct TIMEVAL tval; |
280 | |
313 | |
281 | #if IOM_IDLE |
314 | #if IOM_IDLE |
282 | if (iw.size ()) |
315 | if (iw.size ()) |
… | |
… | |
287 | } |
320 | } |
288 | else |
321 | else |
289 | #endif |
322 | #endif |
290 | { |
323 | { |
291 | #if IOM_TIME |
324 | #if IOM_TIME |
292 | time_watcher *next; |
325 | // find earliest active watcher |
|
|
326 | time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times |
293 | |
327 | |
294 | for (;;) |
328 | for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); ) |
|
|
329 | if (*i && (*i)->at < next->at) |
|
|
330 | next = *i; |
|
|
331 | |
|
|
332 | if (next->at > NOW && next != tw[0]) |
295 | { |
333 | { |
296 | next = tw[0]; // the first time-watcher must exist at ALL times |
|
|
297 | |
|
|
298 | for (int i = tw.size (); i--; ) |
|
|
299 | if (!tw[i]) |
|
|
300 | tw.erase_unordered (i); |
|
|
301 | else if (tw[i]->at < next->at) |
|
|
302 | next = tw[i]; |
|
|
303 | |
|
|
304 | if (next->at > NOW) |
|
|
305 | { |
|
|
306 | if (next != tw[0]) |
|
|
307 | { |
|
|
308 | double diff = next->at - NOW; |
334 | double diff = next->at - NOW; |
309 | tval.tv_sec = (int)diff; |
335 | tval.tv_sec = (int)diff; |
310 | tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); |
336 | tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); |
311 | to = &tval; |
337 | to = &tval; |
312 | } |
|
|
313 | break; |
|
|
314 | } |
|
|
315 | else |
|
|
316 | { |
|
|
317 | unreg (*next); |
|
|
318 | next->call (*next); |
|
|
319 | } |
|
|
320 | } |
338 | } |
321 | #endif |
|
|
322 | } |
|
|
323 | |
|
|
324 | #if IOM_CHECK |
|
|
325 | tw.activity = false; |
|
|
326 | |
|
|
327 | for (int i = cw.size (); i--; ) |
|
|
328 | if (!cw[i]) |
|
|
329 | cw.erase_unordered (i); |
|
|
330 | else |
|
|
331 | cw[i]->call (*cw[i]); |
|
|
332 | |
|
|
333 | if (tw.activity) |
|
|
334 | { |
|
|
335 | tval.tv_sec = 0; |
|
|
336 | tval.TV_FRAC = 0; |
|
|
337 | to = &tval; |
|
|
338 | } |
339 | } |
339 | #endif |
340 | #endif |
340 | |
341 | |
341 | #if IOM_IO || IOM_SIG |
342 | #if IOM_IO || IOM_SIG |
342 | fd_set rfd, wfd; |
343 | fd_set rfd, wfd; |
… | |
… | |
345 | FD_ZERO (&wfd); |
346 | FD_ZERO (&wfd); |
346 | |
347 | |
347 | int fds = 0; |
348 | int fds = 0; |
348 | |
349 | |
349 | # if IOM_IO |
350 | # if IOM_IO |
350 | for (io_manager_vec<io_watcher>::iterator i = iow.end (); i-- > iow.begin (); ) |
351 | for (io_manager_vec<io_watcher>::const_iterator i = iow.end (); i-- > iow.begin (); ) |
351 | if (*i) |
352 | if (*i) |
352 | { |
353 | { |
353 | if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); |
354 | if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); |
354 | if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd); |
355 | if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd); |
355 | |
356 | |
356 | if ((*i)->fd >= fds) fds = (*i)->fd + 1; |
357 | if ((*i)->fd >= fds) fds = (*i)->fd + 1; |
357 | } |
358 | } |
358 | # endif |
359 | # endif |
359 | |
360 | |
360 | if (!to && !fds) //TODO: also check idle_watchers and check_watchers |
361 | if (!to && !fds) //TODO: also check idle_watchers and check_watchers? |
361 | break; // no events |
362 | break; // no events |
362 | |
363 | |
363 | # if IOM_SIG |
364 | # if IOM_SIG |
364 | FD_SET (sigpipe[0], &rfd); |
365 | FD_SET (sigpipe[0], &rfd); |
365 | if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; |
366 | if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; |
… | |
… | |
387 | char ch; |
388 | char ch; |
388 | |
389 | |
389 | while (read (sigpipe[0], &ch, 1) > 0) |
390 | while (read (sigpipe[0], &ch, 1) > 0) |
390 | ; |
391 | ; |
391 | |
392 | |
392 | for (sig_vec **svp = sw.end (); svp-- > sw.begin (); ) |
393 | for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); ) |
393 | if (*svp && (*svp)->pending) |
394 | if (*svp && (*svp)->pending) |
394 | { |
395 | { |
395 | sig_vec &sv = **svp; |
396 | sig_vec &sv = **svp; |
396 | for (int i = sv.size (); i--; ) |
397 | for (int i = sv.size (); i--; ) |
397 | if (!sv[i]) |
398 | if (!sv[i]) |