Deleted Added
full compact
rpoll.c (155420) rpoll.c (165009)
1/*
2 * Copyright (c)1996-2002 by Hartmut Brandt
3 * All rights reserved.
4 *
5 * Author: Hartmut Brandt
6 *
7 * Redistribution of this software and documentation and use in source and
8 * binary forms, with or without modification, are permitted provided that

--- 87 unchanged lines hidden (view full) ---

96
97# ifdef BROKEN_SELECT_PROTO
98# define SELECT_CAST(P) (int *)P
99# else
100# define SELECT_CAST(P) P
101# endif
102
103
1/*
2 * Copyright (c)1996-2002 by Hartmut Brandt
3 * All rights reserved.
4 *
5 * Author: Hartmut Brandt
6 *
7 * Redistribution of this software and documentation and use in source and
8 * binary forms, with or without modification, are permitted provided that

--- 87 unchanged lines hidden (view full) ---

96
97# ifdef BROKEN_SELECT_PROTO
98# define SELECT_CAST(P) (int *)P
99# else
100# define SELECT_CAST(P) P
101# endif
102
103
104typedef signed long long tval_t;
104typedef int64_t tval_t;
105
105
106static inline tval_t GETMSECS(void);
106static inline tval_t GETUSECS(void);
107
108static inline tval_t
107
108static inline tval_t
109GETMSECS(void) {
109GETUSECS(void) {
110 struct timeval tval;
111
112 (void)gettimeofday(&tval, NULL);
110 struct timeval tval;
111
112 (void)gettimeofday(&tval, NULL);
113 return (tval_t)tval.tv_sec*1000+tval.tv_usec/1000;
113 return (tval_t)tval.tv_sec * 1000000 + tval.tv_usec;
114}
115
116/*
117 * Simple fatal exit.
118 */
119static void
120_panic(const char *fmt, ...)
121{

--- 43 unchanged lines hidden (view full) ---

165 struct pollfd *pfd; /* pointer to corresponding poll() structure */
166# endif
167} PollReg_t;
168
169/*
170 * Now for timers
171 */
172typedef struct {
114}
115
116/*
117 * Simple fatal exit.
118 */
119static void
120_panic(const char *fmt, ...)
121{

--- 43 unchanged lines hidden (view full) ---

165 struct pollfd *pfd; /* pointer to corresponding poll() structure */
166# endif
167} PollReg_t;
168
169/*
170 * Now for timers
171 */
172typedef struct {
173 u_int msecs; /* millisecond value of the timer */
173 uint64_t usecs; /* microsecond value of the timer */
174 int repeat; /* one shot or repeat? */
175 void *arg; /* client arg */
176 timer_f func; /* handler, 0 means disfunct */
174 int repeat; /* one shot or repeat? */
175 void *arg; /* client arg */
176 timer_f func; /* handler, 0 means disfunct */
177 tval_t when; /* next time to trigger in msecs! */
177 tval_t when; /* next time to trigger in usecs! */
178} PollTim_t;
179
180/* how many records should our table grow at once? */
181# define POLL_REG_GROW 100
182
183# ifdef USE_POLL
184static struct pollfd * pfd; /* fd list for poll() */
185# endif

--- 105 unchanged lines hidden (view full) ---

291
292 regs_used++;
293 rebuild = 1;
294 }
295
296 poll_unblocksig();
297
298 if(rpoll_trace)
178} PollTim_t;
179
180/* how many records should our table grow at once? */
181# define POLL_REG_GROW 100
182
183# ifdef USE_POLL
184static struct pollfd * pfd; /* fd list for poll() */
185# endif

--- 105 unchanged lines hidden (view full) ---

291
292 regs_used++;
293 rebuild = 1;
294 }
295
296 poll_unblocksig();
297
298 if(rpoll_trace)
299 fprintf(stderr, "poll_register(%d, %#lx, %#lx, %#x)->%d",
300 fd, (u_long)func, (u_long)arg, mask, p - regs);
299 fprintf(stderr, "poll_register(%d, %p, %p, %#x)->%tu",
300 fd, (void *)func, (void *)arg, mask, p - regs);
301 return p - regs;
302}
303
304/*
305 * remove registration
306 */
307void
308poll_unregister(int handle)

--- 59 unchanged lines hidden (view full) ---

368 FD_SET(p->fd, &xset);
369 }
370# endif
371}
372
373int
374poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg)
375{
301 return p - regs;
302}
303
304/*
305 * remove registration
306 */
307void
308poll_unregister(int handle)

--- 59 unchanged lines hidden (view full) ---

368 FD_SET(p->fd, &xset);
369 }
370# endif
371}
372
373int
374poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg)
375{
376 return (poll_start_utimer((unsigned long long)msecs * 1000,
377 repeat, func, arg));
378}
379
380int
381poll_start_utimer(unsigned long long usecs, int repeat, timer_f func, void *arg)
382{
376 PollTim_t *p;
377
378 /* find unused entry */
379 for(p = tims; p < &tims[tims_alloc]; p++)
380 if(p->func == NULL)
381 break;
382
383 if(p == &tims[tims_alloc]) {
384 if(tims_alloc == tims_used) {
385 size_t newsize = tims_alloc + POLL_REG_GROW;
386 tims = _xrealloc(tims, sizeof(tims[0]) * newsize);
387 for(p = &tims[tims_alloc]; p < &tims[newsize]; p++)
388 p->func = NULL;
389 p = &tims[tims_alloc];
390 tims_alloc = newsize;
391 }
392 }
393
394 /* create entry */
383 PollTim_t *p;
384
385 /* find unused entry */
386 for(p = tims; p < &tims[tims_alloc]; p++)
387 if(p->func == NULL)
388 break;
389
390 if(p == &tims[tims_alloc]) {
391 if(tims_alloc == tims_used) {
392 size_t newsize = tims_alloc + POLL_REG_GROW;
393 tims = _xrealloc(tims, sizeof(tims[0]) * newsize);
394 for(p = &tims[tims_alloc]; p < &tims[newsize]; p++)
395 p->func = NULL;
396 p = &tims[tims_alloc];
397 tims_alloc = newsize;
398 }
399 }
400
401 /* create entry */
395 p->msecs = msecs;
402 p->usecs = usecs;
396 p->repeat = repeat;
397 p->arg = arg;
398 p->func = func;
403 p->repeat = repeat;
404 p->arg = arg;
405 p->func = func;
399 p->when = GETMSECS() + msecs;
406 p->when = GETUSECS() + usecs;
400
401 tims_used++;
402
403 resort = 1;
404
405 if(rpoll_trace)
407
408 tims_used++;
409
410 resort = 1;
411
412 if(rpoll_trace)
406 fprintf(stderr, "poll_start_timer(%u, %d, %#lx, %#lx)->%u",
407 msecs, repeat, (u_long)func, (u_long)arg, p - tims);
413 fprintf(stderr, "poll_start_utimer(%llu, %d, %p, %p)->%tu",
414 usecs, repeat, (void *)func, (void *)arg, p - tims);
408
409 return p - tims;
410}
411
412/*
413 * Here we have to look into the sorted table, whether any entry there points
414 * into the registration table for the deleted entry. This is needed,
415 * because a unregistration can occure while we are scanning through the

--- 76 unchanged lines hidden (view full) ---

492 * to be called. So we clear pfd in unregister and check here.
493 */
494void
495poll_dispatch(int wait)
496{
497 u_int i, idx;
498 int ret;
499 tval_t now;
415
416 return p - tims;
417}
418
419/*
420 * Here we have to look into the sorted table, whether any entry there points
421 * into the registration table for the deleted entry. This is needed,
422 * because a unregistration can occure while we are scanning through the

--- 76 unchanged lines hidden (view full) ---

499 * to be called. So we clear pfd in unregister and check here.
500 */
501void
502poll_dispatch(int wait)
503{
504 u_int i, idx;
505 int ret;
506 tval_t now;
500 int tout;
507 tval_t tout;
501 static u_int last_index;
502
503# ifdef USE_SELECT
504 fd_set nrset, nwset, nxset;
505 struct timeval tv;
506# endif
507
508 in_dispatch = 1;

--- 5 unchanged lines hidden (view full) ---

514 if(resort) {
515 resort = 0;
516 sort_timers();
517 }
518
519 /* in wait mode - compute the timeout */
520 if(wait) {
521 if(tfd_used) {
508 static u_int last_index;
509
510# ifdef USE_SELECT
511 fd_set nrset, nwset, nxset;
512 struct timeval tv;
513# endif
514
515 in_dispatch = 1;

--- 5 unchanged lines hidden (view full) ---

521 if(resort) {
522 resort = 0;
523 sort_timers();
524 }
525
526 /* in wait mode - compute the timeout */
527 if(wait) {
528 if(tfd_used) {
522 now = GETMSECS();
529 now = GETUSECS();
523# ifdef DEBUG
524 {
530# ifdef DEBUG
531 {
525 fprintf(stderr, "now=%"QUADFMT"u", now);
532 fprintf(stderr, "now=%llu", now);
526 for(i = 0; i < tims_used; i++)
533 for(i = 0; i < tims_used; i++)
527 fprintf(stderr, "timers[%2d] = %"QUADFMT"d", i, tfd[i]->when - now);
534 fprintf(stderr, "timers[%2d] = %lld",
535 i, tfd[i]->when - now);
528 }
529# endif
530 if((tout = tims[tfd[0]].when - now) < 0)
531 tout = 0;
532 } else
533 tout = INFTIM;
534 } else
535 tout = 0;
536
537# ifdef DEBUG
538 fprintf(stderr, "rpoll -- selecting with tout=%u", tout);
539# endif
540
541# ifdef USE_POLL
536 }
537# endif
538 if((tout = tims[tfd[0]].when - now) < 0)
539 tout = 0;
540 } else
541 tout = INFTIM;
542 } else
543 tout = 0;
544
545# ifdef DEBUG
546 fprintf(stderr, "rpoll -- selecting with tout=%u", tout);
547# endif
548
549# ifdef USE_POLL
542 ret = poll(pfd, regs_used, tout);
550 ret = poll(pfd, regs_used, tout == INFTIM ? INFTIM : (tout / 1000));
543# endif
544
545# ifdef USE_SELECT
546 nrset = rset;
547 nwset = wset;
548 nxset = xset;
549 if(tout != INFTIM) {
551# endif
552
553# ifdef USE_SELECT
554 nrset = rset;
555 nwset = wset;
556 nxset = xset;
557 if(tout != INFTIM) {
550 tv.tv_sec = tout / 1000;
551 tv.tv_usec = (tout % 1000) * 1000;
558 tv.tv_sec = tout / 1000000;
559 tv.tv_usec = tout % 1000000;
552 }
553 ret = select(maxfd+1,
554 SELECT_CAST(&nrset),
555 SELECT_CAST(&nwset),
560 }
561 ret = select(maxfd+1,
562 SELECT_CAST(&nrset),
563 SELECT_CAST(&nwset),
556 SELECT_CAST(&nxset), (tout==INFTIM) ? 0 : &tv);
564 SELECT_CAST(&nxset), (tout==INFTIM) ? NULL : &tv);
557# endif
558
559 if(ret == -1) {
560 if(errno == EINTR)
561 return;
562 _panic("poll/select: %s", strerror(errno));
563 }
564

--- 4 unchanged lines hidden (view full) ---

569
570 assert(idx < regs_alloc);
571
572 if(regs[idx].fd >= 0) {
573 int mask = 0;
574
575# ifdef USE_POLL
576 if(regs[idx].pfd) {
565# endif
566
567 if(ret == -1) {
568 if(errno == EINTR)
569 return;
570 _panic("poll/select: %s", strerror(errno));
571 }
572

--- 4 unchanged lines hidden (view full) ---

577
578 assert(idx < regs_alloc);
579
580 if(regs[idx].fd >= 0) {
581 int mask = 0;
582
583# ifdef USE_POLL
584 if(regs[idx].pfd) {
577 if(regs[idx].pfd->revents & poll_in)
585 if ((regs[idx].mask & POLL_IN) &&
586 (regs[idx].pfd->revents & poll_in))
578 mask |= POLL_IN;
587 mask |= POLL_IN;
579 if(regs[idx].pfd->revents & poll_out)
588 if ((regs[idx].mask & POLL_OUT) &&
589 (regs[idx].pfd->revents & poll_out))
580 mask |= POLL_OUT;
590 mask |= POLL_OUT;
581 if(regs[idx].pfd->revents & poll_except)
591 if((regs[idx].mask & POLL_EXCEPT) &&
592 (regs[idx].pfd->revents & poll_except))
582 mask |= POLL_EXCEPT;
583 }
584# endif
585# ifdef USE_SELECT
593 mask |= POLL_EXCEPT;
594 }
595# endif
596# ifdef USE_SELECT
586 if(FD_ISSET(regs[idx].fd, &nrset))
597 if ((regs[idx].mask & POLL_IN) &&
598 FD_ISSET(regs[idx].fd, &nrset))
587 mask |= POLL_IN;
599 mask |= POLL_IN;
588 if(FD_ISSET(regs[idx].fd, &nwset))
600 if ((regs[idx].mask & POLL_OUT) &&
601 FD_ISSET(regs[idx].fd, &nwset))
589 mask |= POLL_OUT;
602 mask |= POLL_OUT;
590 if(FD_ISSET(regs[idx].fd, &nxset))
603 if ((regs[idx].mask & POLL_EXCEPT) &&
604 FD_ISSET(regs[idx].fd, &nxset))
591 mask |= POLL_EXCEPT;
592# endif
593 assert(idx < regs_alloc);
594
595 if(mask) {
596 if(rpoll_trace)
597 fprintf(stderr, "poll_dispatch() -- "
605 mask |= POLL_EXCEPT;
606# endif
607 assert(idx < regs_alloc);
608
609 if(mask) {
610 if(rpoll_trace)
611 fprintf(stderr, "poll_dispatch() -- "
598 "file %d/%d",
599 regs[idx].fd, idx);
612 "file %d/%d %x",
613 regs[idx].fd, idx, mask);
600 (*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg);
601 }
602 }
603
604 }
605 last_index++;
606 }
607
608 /* dispatch timeouts */
609 if(tfd_used) {
614 (*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg);
615 }
616 }
617
618 }
619 last_index++;
620 }
621
622 /* dispatch timeouts */
623 if(tfd_used) {
610 now = GETMSECS();
624 now = GETUSECS();
611 for(i = 0; i < tfd_used; i++) {
612 if(tfd[i] < 0)
613 continue;
614 if(tims[tfd[i]].when > now)
615 break;
616 if(rpoll_trace)
617 fprintf(stderr, "rpoll_dispatch() -- timeout %d",tfd[i]);
618 (*tims[tfd[i]].func)(tfd[i], tims[tfd[i]].arg);
619 if(tfd[i] < 0)
620 continue;
621 if(tims[tfd[i]].repeat)
625 for(i = 0; i < tfd_used; i++) {
626 if(tfd[i] < 0)
627 continue;
628 if(tims[tfd[i]].when > now)
629 break;
630 if(rpoll_trace)
631 fprintf(stderr, "rpoll_dispatch() -- timeout %d",tfd[i]);
632 (*tims[tfd[i]].func)(tfd[i], tims[tfd[i]].arg);
633 if(tfd[i] < 0)
634 continue;
635 if(tims[tfd[i]].repeat)
622 tims[tfd[i]].when = now + tims[tfd[i]].msecs;
636 tims[tfd[i]].when = now + tims[tfd[i]].usecs;
623 else {
624 tims[tfd[i]].func = NULL;
625 tims_used--;
626 tfd[i] = -1;
627 }
628 resort = 1;
629 }
630 }

--- 8 unchanged lines hidden (view full) ---

639double elaps(void);
640void infunc(int fd, int mask, void *arg);
641
642double
643elaps(void)
644{
645 gettimeofday(&now, NULL);
646
637 else {
638 tims[tfd[i]].func = NULL;
639 tims_used--;
640 tfd[i] = -1;
641 }
642 resort = 1;
643 }
644 }

--- 8 unchanged lines hidden (view full) ---

653double elaps(void);
654void infunc(int fd, int mask, void *arg);
655
656double
657elaps(void)
658{
659 gettimeofday(&now, NULL);
660
647 return (double)(10 * now.tv_sec + now.tv_usec / 100000 - 10 * start.tv_sec - start.tv_usec / 100000)
648 / 10;
661 return (double)(10 * now.tv_sec + now.tv_usec / 100000 -
662 10 * start.tv_sec - start.tv_usec / 100000) / 10;
649}
650
651void
652infunc(int fd, int mask, void *arg)
653{
654 char buf[1024];
655 int ret;
656

--- 13 unchanged lines hidden (view full) ---

670{
671 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
672}
673void
674tfunc1(int tid, void *arg)
675{
676 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
677}
663}
664
665void
666infunc(int fd, int mask, void *arg)
667{
668 char buf[1024];
669 int ret;
670

--- 13 unchanged lines hidden (view full) ---

684{
685 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
686}
687void
688tfunc1(int tid, void *arg)
689{
690 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
691}
692void
693tfunc2(int tid, void *arg)
694{
695 static u_int count = 0;
678
696
697 if (++count % 10000 == 0)
698 printf("%4.1f -- %d\n", elaps(), tid);
699}
700
679void first(int tid, void *arg);
680void second(int tid, void *arg);
681
682void
683second(int tid, void *arg)
684{
685 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
701void first(int tid, void *arg);
702void second(int tid, void *arg);
703
704void
705second(int tid, void *arg)
706{
707 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
686 poll_start_timer(5500, 0, first, "first");
708 poll_start_utimer(5500000, 0, first, "first");
687 poll_stop_timer(t1);
688 t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
689}
690void
691first(int tid, void *arg)
692{
693 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
694 poll_start_timer(3700, 0, second, "second");
695 poll_stop_timer(t0);
696 t1 = poll_start_timer(250, 1, tfunc1, "1/4 second");
697}
698
699int
700main(int argc, char *argv[])
701{
709 poll_stop_timer(t1);
710 t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
711}
712void
713first(int tid, void *arg)
714{
715 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg);
716 poll_start_timer(3700, 0, second, "second");
717 poll_stop_timer(t0);
718 t1 = poll_start_timer(250, 1, tfunc1, "1/4 second");
719}
720
721int
722main(int argc, char *argv[])
723{
702 argc = argc;
703 argv = argv;
704 gettimeofday(&start, NULL);
705 poll_register(0, infunc, NULL, POLL_IN);
724 argv = argv;
725 gettimeofday(&start, NULL);
726 poll_register(0, infunc, NULL, POLL_IN);
706 t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
707 poll_start_timer(2500, 0, first, "first");
708
727
728 if (argc < 2) {
729 t0 = poll_start_timer(1000, 1, tfunc0, "1 second");
730 poll_start_timer(2500, 0, first, "first");
731 } else {
732 t0 = poll_start_utimer(300, 1, tfunc2, NULL);
733 }
734
709 while(1)
710 poll_dispatch(1);
711
712 return 0;
713}
714# endif
735 while(1)
736 poll_dispatch(1);
737
738 return 0;
739}
740# endif