… | |
… | |
33 | # include <time.h> |
33 | # include <time.h> |
34 | #endif |
34 | #endif |
35 | |
35 | |
36 | // for IOM_SIG |
36 | // for IOM_SIG |
37 | #if IOM_SIG |
37 | #if IOM_SIG |
38 | # include <signal.h> |
38 | # include <csignal> |
39 | # include <fcntl.h> |
39 | # include <fcntl.h> |
40 | #endif |
40 | #endif |
41 | |
41 | |
42 | // if the BSDs would at least be marginally POSIX-compatible.. *sigh* |
42 | // if the BSDs would at least be marginally POSIX-compatible.. *sigh* |
43 | // until that happens, sys/select.h must come last |
43 | // until that happens, sys/select.h must come last |
… | |
… | |
94 | } tw0; |
94 | } tw0; |
95 | |
95 | |
96 | tstamp NOW; |
96 | tstamp NOW; |
97 | |
97 | |
98 | #if IOM_TIME |
98 | #if IOM_TIME |
99 | inline void set_now (void) |
99 | tstamp io_manager::now () |
100 | { |
100 | { |
101 | struct timeval tv; |
101 | struct timeval tv; |
102 | |
102 | |
103 | gettimeofday (&tv, 0); |
103 | gettimeofday (&tv, 0); |
104 | NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.; |
104 | return (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.; |
|
|
105 | } |
|
|
106 | |
|
|
107 | void io_manager::set_now () |
|
|
108 | { |
|
|
109 | NOW = now (); |
105 | } |
110 | } |
106 | #endif |
111 | #endif |
107 | |
112 | |
108 | static bool iom_valid; |
113 | static bool iom_valid; |
109 | |
114 | |
… | |
… | |
118 | { |
123 | { |
119 | perror ("io_manager: unable to create signal pipe, aborting."); |
124 | perror ("io_manager: unable to create signal pipe, aborting."); |
120 | abort (); |
125 | abort (); |
121 | } |
126 | } |
122 | |
127 | |
123 | fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); |
128 | fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); fcntl (sigpipe[0], F_SETFD, FD_CLOEXEC); |
124 | fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); |
129 | fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); fcntl (sigpipe[1], F_SETFD, FD_CLOEXEC); |
125 | #endif |
130 | #endif |
126 | |
131 | |
127 | iom_valid = true; |
132 | iom_valid = true; |
128 | |
133 | |
129 | #if IOM_TIME |
134 | #if IOM_TIME |
130 | set_now (); |
135 | io_manager::set_now (); |
131 | |
136 | |
132 | tw0.start (TSTAMP_MAX); |
137 | tw0.start (TSTAMP_MAX); |
133 | #endif |
138 | #endif |
134 | } |
139 | } |
135 | |
140 | |
… | |
… | |
283 | activity = false; |
288 | activity = false; |
284 | |
289 | |
285 | for (int i = tw.size (); i--; ) |
290 | for (int i = tw.size (); i--; ) |
286 | if (!tw[i]) |
291 | if (!tw[i]) |
287 | tw.erase_unordered (i); |
292 | tw.erase_unordered (i); |
288 | else if (tw[i]->at <= NOW + IOM_ACCURACY) |
293 | else if (tw[i]->at <= NOW) |
289 | { |
294 | { |
290 | time_watcher &w = *tw[i]; |
295 | time_watcher &w = *tw[i]; |
291 | |
296 | |
292 | unreg (w); |
297 | unreg (w); |
293 | w.call (w); |
298 | w.call (w); |
… | |
… | |
375 | # if IOM_SIG |
380 | # if IOM_SIG |
376 | sigprocmask (SIG_BLOCK, &sigs, NULL); |
381 | sigprocmask (SIG_BLOCK, &sigs, NULL); |
377 | # endif |
382 | # endif |
378 | |
383 | |
379 | # if IOM_TIME |
384 | # if IOM_TIME |
|
|
385 | { |
|
|
386 | // update time, try to compensate for gross non-monotonic time changes |
|
|
387 | tstamp diff = NOW; |
380 | set_now (); |
388 | set_now (); |
|
|
389 | diff = NOW - diff; |
|
|
390 | |
|
|
391 | if (diff < 0) |
|
|
392 | for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); ) |
|
|
393 | if (*i) |
|
|
394 | (*i)->at += diff; |
|
|
395 | } |
381 | # endif |
396 | # endif |
382 | |
397 | |
383 | if (fds > 0) |
398 | if (fds > 0) |
384 | { |
399 | { |
385 | # if IOM_SIG |
400 | # if IOM_SIG |
… | |
… | |
388 | char ch; |
403 | char ch; |
389 | |
404 | |
390 | while (read (sigpipe[0], &ch, 1) > 0) |
405 | while (read (sigpipe[0], &ch, 1) > 0) |
391 | ; |
406 | ; |
392 | |
407 | |
393 | for (sig_vec **svp = sw.end (); svp-- > sw.begin (); ) |
408 | for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); ) |
394 | if (*svp && (*svp)->pending) |
409 | if (*svp && (*svp)->pending) |
395 | { |
410 | { |
396 | sig_vec &sv = **svp; |
411 | sig_vec &sv = **svp; |
397 | for (int i = sv.size (); i--; ) |
412 | for (int i = sv.size (); i--; ) |
398 | if (!sv[i]) |
413 | if (!sv[i]) |
… | |
… | |
409 | for (int i = iow.size (); i--; ) |
424 | for (int i = iow.size (); i--; ) |
410 | if (!iow[i]) |
425 | if (!iow[i]) |
411 | iow.erase_unordered (i); |
426 | iow.erase_unordered (i); |
412 | else |
427 | else |
413 | { |
428 | { |
|
|
429 | io_watcher &w = *iow[i]; |
414 | short revents = iow[i]->events; |
430 | short revents = w.events; |
415 | |
431 | |
416 | if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ; |
432 | if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ; |
417 | if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE; |
433 | if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE; |
418 | |
434 | |
419 | if (revents) |
435 | if (revents) |
420 | iow[i]->call (*iow[i], revents); |
436 | w.call (w, revents); |
421 | } |
437 | } |
422 | #endif |
438 | #endif |
423 | } |
439 | } |
424 | else if (fds < 0 && errno != EINTR) |
440 | else if (fds < 0 && errno != EINTR) |
425 | { |
441 | { |