ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/iom.C
(Generate patch)

Comparing rxvt-unicode/src/iom.C (file contents):
Revision 1.37 by root, Mon Feb 12 17:34:58 2007 UTC vs.
Revision 1.38 by root, Thu Oct 25 10:44:14 2007 UTC

49 49
50#define TIMEVAL timeval 50#define TIMEVAL timeval
51#define TV_FRAC tv_usec 51#define TV_FRAC tv_usec
52#define TV_MULT 1000000L 52#define TV_MULT 1000000L
53 53
54#ifndef IOM_LIBEVENT
54#if IOM_IO 55#if IOM_IO
55static io_manager_vec<io_watcher> iow; 56static io_manager_vec<io_watcher> iow;
56#endif 57#endif
58#if IOM_TIME
59static io_manager_vec<time_watcher> tw;
60#endif
61#endif
62
57#if IOM_CHECK 63#if IOM_CHECK
58static io_manager_vec<check_watcher> cw; 64static io_manager_vec<check_watcher> cw;
59#endif 65#endif
60#if IOM_TIME
61static io_manager_vec<time_watcher> tw;
62#endif
63#if IOM_IDLE 66#if IOM_IDLE
64static io_manager_vec<idle_watcher> iw; 67static io_manager_vec<idle_watcher> iw;
65#endif 68#endif
69
66#if IOM_SIG 70#if IOM_SIG
67static int sigpipe[2]; // signal signalling pipe 71static int sigpipe[2]; // signal signalling pipe
68static sigset_t sigs; 72static sigset_t sigs;
69struct sig_vec : io_manager_vec<sig_watcher> { 73struct sig_vec : io_manager_vec<sig_watcher> {
70 int pending; 74 int pending;
72 : pending (false) 76 : pending (false)
73 { } 77 { }
74}; 78};
75static vector<sig_vec *> sw; 79static vector<sig_vec *> sw;
76#endif 80#endif
81
77#if IOM_CHILD 82#if IOM_CHILD
78static io_manager_vec<child_watcher> pw; 83static io_manager_vec<child_watcher> pw;
79#endif 84#endif
80 85
81// this is a dummy time watcher to ensure that the first 86// this is a dummy time watcher to ensure that the first
152 init () 157 init ()
153 { 158 {
154#ifdef IOM_PREINIT 159#ifdef IOM_PREINIT
155 { IOM_PREINIT } 160 { IOM_PREINIT }
156#endif 161#endif
162#ifdef IOM_LIBEVENT
163 event_init ();
164#endif
157 iom_valid = true; 165 iom_valid = true;
158 166
159#if IOM_SIG 167#if IOM_SIG
160 sigemptyset (&sigs); 168 sigemptyset (&sigs);
161 169
227 w.active = 0; 235 w.active = 0;
228 } 236 }
229} 237}
230 238
231#if IOM_TIME 239#if IOM_TIME
240# ifdef IOM_LIBEVENT
241 void iom_time_c_callback (int fd, short events, void *data)
242 {
243 time_watcher *w = static_cast<time_watcher *>(data);
244 w->call (*w);
245 }
246# else
247 void io_manager::reg (time_watcher &w) { io_manager::reg (w, tw); }
248 void io_manager::unreg (time_watcher &w) { io_manager::unreg (w, tw); }
249# endif
250
232void time_watcher::trigger () 251void time_watcher::trigger ()
233{ 252{
234 call (*this); 253 call (*this);
235 io_manager::reg (*this); 254 start ();
236} 255}
237
238void io_manager::reg (time_watcher &w) { io_manager::reg (w, tw); }
239void io_manager::unreg (time_watcher &w) { io_manager::unreg (w, tw); }
240#endif 256#endif
241 257
242#if IOM_IO 258#if IOM_IO
259# ifdef IOM_LIBEVENT
260 void iom_io_c_callback (int fd, short events, void *data)
261 {
262 io_watcher *w = static_cast<io_watcher *>(data);
263 w->call (*w, events);
264 }
265# else
243void io_manager::reg (io_watcher &w) { io_manager::reg (w, iow); } 266 void io_manager::reg (io_watcher &w) { io_manager::reg (w, iow); }
244void io_manager::unreg (io_watcher &w) { io_manager::unreg (w, iow); } 267 void io_manager::unreg (io_watcher &w) { io_manager::unreg (w, iow); }
268# endif
245#endif 269#endif
246 270
247#if IOM_CHECK 271#if IOM_CHECK
248void io_manager::reg (check_watcher &w) { io_manager::reg (w, cw); } 272void io_manager::reg (check_watcher &w) { io_manager::reg (w, cw); }
249void io_manager::unreg (check_watcher &w) { io_manager::unreg (w, cw); } 273void io_manager::unreg (check_watcher &w) { io_manager::unreg (w, cw); }
327 351
328void io_manager::loop () 352void io_manager::loop ()
329{ 353{
330 init::required (); 354 init::required ();
331 355
332#if IOM_TIME 356 #if IOM_TIME
333 set_now (); 357 set_now ();
334#endif 358 #endif
335 359
336 for (;;) 360 for (;;)
337 { 361 {
338 362 #ifndef IOM_LIBEVENT
339#if IOM_TIME 363 #if IOM_TIME
340 // call pending time watchers 364 // call pending time watchers
341 { 365 {
342 bool activity; 366 bool activity;
343 367
344 do 368 do
345 { 369 {
346 activity = false; 370 activity = false;
347 371
348 for (int i = tw.size (); i--; ) 372 for (int i = tw.size (); i--; )
349 if (!tw[i]) 373 if (!tw[i])
350 tw.erase_unordered (i); 374 tw.erase_unordered (i);
351 else if (tw[i]->at <= NOW) 375 else if (tw[i]->at <= NOW)
352 { 376 {
353 time_watcher &w = *tw[i]; 377 time_watcher &w = *tw[i];
378
379 unreg (w);
380 w.call (w);
381
382 activity = true;
354 383 }
355 unreg (w);
356 w.call (w);
357
358 activity = true;
359 }
360 } 384 }
361 while (activity); 385 while (activity);
362 } 386 }
363#endif 387 #endif
388 #endif
364 389
365#if IOM_CHECK 390 #if IOM_CHECK
366 // call all check watchers 391 // call all check watchers
367 for (int i = cw.size (); i--; ) 392 for (int i = cw.size (); i--; )
368 if (!cw[i]) 393 if (!cw[i])
369 cw.erase_unordered (i); 394 cw.erase_unordered (i);
370 else 395 else
371 cw[i]->call (*cw[i]); 396 cw[i]->call (*cw[i]);
372#endif 397 #endif
373 398
374 struct TIMEVAL *to = 0; 399 struct TIMEVAL *to = 0;
375 struct TIMEVAL tval; 400 struct TIMEVAL tval;
376 401
377#if IOM_IDLE 402#if IOM_IDLE
381 tval.TV_FRAC = 0; 406 tval.TV_FRAC = 0;
382 to = &tval; 407 to = &tval;
383 } 408 }
384 else 409 else
385#endif 410#endif
411#ifndef IOM_LIBEVENT
386 { 412 {
387#if IOM_TIME 413 #if IOM_TIME
388 // find earliest active watcher 414 // find earliest active watcher
389 time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times 415 time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times
390 416
391 for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); ) 417 for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
392 if (*i && (*i)->at < next->at) 418 if (*i && (*i)->at < next->at)
393 next = *i; 419 next = *i;
394 420
395 if (next->at > NOW && next != tw[0]) 421 if (next->at > NOW && next != tw[0])
396 { 422 {
397 double diff = next->at - NOW; 423 double diff = next->at - NOW;
398 tval.tv_sec = (int)diff; 424 tval.tv_sec = (int)diff;
399 tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); 425 tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT);
400 to = &tval; 426 to = &tval;
401 } 427 }
428 #endif
402 } 429 }
403#endif
404 430
405#if IOM_IO || IOM_SIG 431#if IOM_IO || IOM_SIG
406 fd_set rfd, wfd; 432 fd_set rfd, wfd;
407 433
408 FD_ZERO (&rfd); 434 FD_ZERO (&rfd);
409 FD_ZERO (&wfd); 435 FD_ZERO (&wfd);
410 436
411 int fds = 0; 437 int fds = 0;
412 438
413# if IOM_IO 439 #if IOM_IO
414 for (io_manager_vec<io_watcher>::const_iterator i = iow.end (); i-- > iow.begin (); ) 440 for (io_manager_vec<io_watcher>::const_iterator i = iow.end (); i-- > iow.begin (); )
415 if (*i) 441 if (*i)
416 { 442 {
417 if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); 443 if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd);
418 if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd); 444 if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd);
419 445
420 if ((*i)->fd >= fds) fds = (*i)->fd + 1; 446 if ((*i)->fd >= fds) fds = (*i)->fd + 1;
421 } 447 }
422# endif 448 #endif
423 449
424 if (!to && !fds) //TODO: also check idle_watchers and check_watchers? 450 if (!to && !fds) //TODO: also check idle_watchers and check_watchers?
425 break; // no events 451 break; // no events
426 452
427# if IOM_SIG 453 #if IOM_SIG
428 FD_SET (sigpipe[0], &rfd); 454 FD_SET (sigpipe[0], &rfd);
429 if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; 455 if (sigpipe[0] >= fds) fds = sigpipe[0] + 1;
430# endif 456 #endif
431 457
432# if IOM_SIG 458 #if IOM_SIG
433 // there is no race, as we use a pipe for signals, so select 459 // there is no race, as we use a pipe for signals, so select
434 // will return if a signal is caught. 460 // will return if a signal is caught.
435 sigprocmask (SIG_UNBLOCK, &sigs, NULL); 461 sigprocmask (SIG_UNBLOCK, &sigs, NULL);
436# endif 462 #endif
437 fds = select (fds, &rfd, &wfd, NULL, to); 463 fds = select (fds, &rfd, &wfd, NULL, to);
438# if IOM_SIG 464 #if IOM_SIG
439 sigprocmask (SIG_BLOCK, &sigs, NULL); 465 sigprocmask (SIG_BLOCK, &sigs, NULL);
466 #endif
467
468#else
469 if (to)
470 event_loop (EVLOOP_NONBLOCK);
471 else
472 event_loop (EVLOOP_ONCE);
440# endif 473#endif
441 474
442# if IOM_TIME 475 #if IOM_TIME
443 { 476 {
444 // update time, try to compensate for gross non-monotonic time changes 477 // update time, try to compensate for gross non-monotonic time changes
445 tstamp diff = NOW; 478 tstamp diff = NOW;
446 set_now (); 479 set_now ();
447 diff = NOW - diff; 480 diff = NOW - diff;
448 481
449 if (diff < 0) 482 if (diff < 0)
450 for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); ) 483 for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
451 if (*i) 484 if (*i)
452 (*i)->at += diff; 485 (*i)->at += diff;
453 } 486 }
454# endif 487 #endif
455 488
489#ifndef IOM_LIBEVENT
456 if (fds > 0) 490 if (fds > 0)
457 { 491 {
458# if IOM_SIG 492 #if IOM_SIG
459 if (FD_ISSET (sigpipe[0], &rfd)) 493 if (FD_ISSET (sigpipe[0], &rfd))
460 {
461 char ch;
462
463 while (read (sigpipe[0], &ch, 1) > 0)
464 ;
465
466 for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); )
467 if (*svp && (*svp)->pending)
468 {
469 sig_vec &sv = **svp;
470 for (int i = sv.size (); i--; )
471 if (!sv[i])
472 sv.erase_unordered (i);
473 else
474 sv[i]->call (*sv[i]);
475
476 sv.pending = false;
477 }
478 }
479# endif
480
481# if IOM_IO
482 for (int i = iow.size (); i--; )
483 if (!iow[i])
484 iow.erase_unordered (i);
485 else
486 { 494 {
487 io_watcher &w = *iow[i]; 495 char ch;
488 short revents = w.events;
489 496
490 if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ; 497 while (read (sigpipe[0], &ch, 1) > 0)
491 if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE; 498 ;
492 499
493 if (revents) 500 for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); )
494 w.call (w, revents); 501 if (*svp && (*svp)->pending)
502 {
503 sig_vec &sv = **svp;
504 for (int i = sv.size (); i--; )
505 if (!sv[i])
506 sv.erase_unordered (i);
507 else
508 sv[i]->call (*sv[i]);
509
510 sv.pending = false;
511 }
495 } 512 }
496#endif 513 #endif
514
515 #if IOM_IO
516 for (int i = iow.size (); i--; )
517 if (!iow[i])
518 iow.erase_unordered (i);
519 else
520 {
521 io_watcher &w = *iow[i];
522 short revents = w.events;
523
524 if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ;
525 if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE;
526
527 if (revents)
528 w.call (w, revents);
529 }
530 #endif
497 } 531 }
498 else if (fds < 0 && errno != EINTR) 532 else if (fds < 0 && errno != EINTR)
499 { 533 {
500 perror ("io_manager: fatal error while waiting for I/O or time event, aborting."); 534 perror ("io_manager: fatal error while waiting for I/O or time event, aborting.");
501 abort (); 535 abort ();
502 } 536 }
537#else
538 if (0)
539 ;
540#endif
503#if IOM_IDLE 541#if IOM_IDLE
504 else 542 else
505 for (int i = iw.size (); i--; ) 543 for (int i = iw.size (); i--; )
506 if (!iw[i]) 544 if (!iw[i])
507 iw.erase_unordered (i); 545 iw.erase_unordered (i);
511 549
512#elif IOM_TIME 550#elif IOM_TIME
513 if (!to) 551 if (!to)
514 break; 552 break;
515 553
516 select (0, 0, 0, 0, &to); 554 select (0, 0, 0, 0, to);
517 set_now (); 555 set_now ();
518#else
519 break; 556 break;
520#endif 557#endif
521 } 558 }
522} 559}
523 560

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines