Lines 155-160
Link Here
|
155 |
_pevent_unref(ev); \ |
155 |
_pevent_unref(ev); \ |
156 |
} while (0) |
156 |
} while (0) |
157 |
|
157 |
|
|
|
158 |
#define PEVENT_SET_OCCURRED(ctx, ev) \ |
159 |
do { \ |
160 |
(ev)->flags |= PEVENT_OCCURRED; \ |
161 |
if ((ev) != TAILQ_FIRST(&ctx->events)) { \ |
162 |
TAILQ_REMOVE(&(ctx)->events, (ev), next); \ |
163 |
TAILQ_INSERT_HEAD(&(ctx)->events, (ev), next); \ |
164 |
} \ |
165 |
} while (0) |
166 |
|
158 |
/* Internal functions */ |
167 |
/* Internal functions */ |
159 |
static void pevent_ctx_service(struct pevent *ev); |
168 |
static void pevent_ctx_service(struct pevent *ev); |
160 |
static void *pevent_ctx_main(void *arg); |
169 |
static void *pevent_ctx_main(void *arg); |
Lines 338-344
Link Here
|
338 |
ev->u.millis = 0; |
347 |
ev->u.millis = 0; |
339 |
gettimeofday(&ev->when, NULL); |
348 |
gettimeofday(&ev->when, NULL); |
340 |
ev->when.tv_sec += ev->u.millis / 1000; |
349 |
ev->when.tv_sec += ev->u.millis / 1000; |
341 |
ev->when.tv_usec += ev->u.millis % 1000; |
350 |
ev->when.tv_usec += (ev->u.millis % 1000) * 1000; |
|
|
351 |
if (ev->when.tv_usec > 1000000) { |
352 |
ev->when.tv_sec++; |
353 |
ev->when.tv_usec -= 1000000; |
354 |
} |
342 |
break; |
355 |
break; |
343 |
case PEVENT_MESG_PORT: |
356 |
case PEVENT_MESG_PORT: |
344 |
va_start(args, type); |
357 |
va_start(args, type); |
Lines 394-408
Link Here
|
394 |
} else |
407 |
} else |
395 |
pevent_ctx_notify(ctx); |
408 |
pevent_ctx_notify(ctx); |
396 |
|
409 |
|
|
|
410 |
/* Caller gets the one reference */ |
411 |
ev->peventp = peventp; |
412 |
*peventp = ev; |
413 |
|
397 |
/* Add event to the pending event list */ |
414 |
/* Add event to the pending event list */ |
398 |
PEVENT_ENQUEUE(ctx, ev); |
415 |
PEVENT_ENQUEUE(ctx, ev); |
399 |
|
416 |
|
400 |
/* Unlock context */ |
417 |
/* Unlock context */ |
401 |
MUTEX_UNLOCK(&ctx->mutex, ctx->mutex_count); |
418 |
MUTEX_UNLOCK(&ctx->mutex, ctx->mutex_count); |
402 |
|
419 |
|
403 |
/* Done; caller gets the one reference */ |
|
|
404 |
ev->peventp = peventp; |
405 |
*peventp = ev; |
406 |
return (0); |
420 |
return (0); |
407 |
} |
421 |
} |
408 |
|
422 |
|
Lines 469-475
Link Here
|
469 |
goto done; |
483 |
goto done; |
470 |
|
484 |
|
471 |
/* Mark event as having occurred */ |
485 |
/* Mark event as having occurred */ |
472 |
ev->flags |= PEVENT_OCCURRED; |
486 |
PEVENT_SET_OCCURRED(ctx, ev); |
473 |
|
487 |
|
474 |
/* Wake up thread if event is still in the queue */ |
488 |
/* Wake up thread if event is still in the queue */ |
475 |
if ((ev->flags & PEVENT_ENQUEUED) != 0) |
489 |
if ((ev->flags & PEVENT_ENQUEUED) != 0) |
Lines 523-528
Link Here
|
523 |
struct timeval now; |
537 |
struct timeval now; |
524 |
struct pollfd *fd; |
538 |
struct pollfd *fd; |
525 |
struct pevent *ev; |
539 |
struct pevent *ev; |
|
|
540 |
struct pevent *next_ev; |
526 |
int poll_idx; |
541 |
int poll_idx; |
527 |
int timeout; |
542 |
int timeout; |
528 |
int r; |
543 |
int r; |
Lines 562-567
Link Here
|
562 |
} |
577 |
} |
563 |
} |
578 |
} |
564 |
|
579 |
|
|
|
580 |
/* If we were intentionally woken up, read the wakeup byte */ |
581 |
if (ctx->notified) { |
582 |
DBG(PEVENT, "ctx %p thread was notified", ctx); |
583 |
(void)read(ctx->pipe[0], &pevent_byte, 1); |
584 |
ctx->notified = 0; |
585 |
} |
586 |
|
565 |
/* Add event for the notify pipe */ |
587 |
/* Add event for the notify pipe */ |
566 |
poll_idx = 0; |
588 |
poll_idx = 0; |
567 |
if (ctx->fds_alloc > 0) { |
589 |
if (ctx->fds_alloc > 0) { |
Lines 620-626
Link Here
|
620 |
switch (ev->type) { |
642 |
switch (ev->type) { |
621 |
case PEVENT_MESG_PORT: |
643 |
case PEVENT_MESG_PORT: |
622 |
if (mesg_port_qlen(ev->u.port) > 0) |
644 |
if (mesg_port_qlen(ev->u.port) > 0) |
623 |
ev->flags |= PEVENT_OCCURRED; |
645 |
PEVENT_SET_OCCURRED(ctx, ev); |
624 |
break; |
646 |
break; |
625 |
default: |
647 |
default: |
626 |
break; |
648 |
break; |
Lines 654-660
Link Here
|
654 |
gettimeofday(&now, NULL); |
676 |
gettimeofday(&now, NULL); |
655 |
|
677 |
|
656 |
/* Mark poll() events that have occurred */ |
678 |
/* Mark poll() events that have occurred */ |
657 |
TAILQ_FOREACH(ev, &ctx->events, next) { |
679 |
for (ev = TAILQ_FIRST((&ctx->events)); ev != NULL; ev = next_ev) { |
|
|
680 |
next_ev = TAILQ_NEXT(ev, next); |
658 |
assert(ev->magic == PEVENT_MAGIC); |
681 |
assert(ev->magic == PEVENT_MAGIC); |
659 |
switch (ev->type) { |
682 |
switch (ev->type) { |
660 |
case PEVENT_READ: |
683 |
case PEVENT_READ: |
Lines 664-696
Link Here
|
664 |
fd = &ctx->fds[ev->poll_idx]; |
687 |
fd = &ctx->fds[ev->poll_idx]; |
665 |
if ((fd->revents & ((ev->type == PEVENT_READ) ? |
688 |
if ((fd->revents & ((ev->type == PEVENT_READ) ? |
666 |
READABLE_EVENTS : WRITABLE_EVENTS)) != 0) |
689 |
READABLE_EVENTS : WRITABLE_EVENTS)) != 0) |
667 |
ev->flags |= PEVENT_OCCURRED; |
690 |
PEVENT_SET_OCCURRED(ctx, ev); |
668 |
break; |
691 |
break; |
669 |
case PEVENT_TIME: |
692 |
case PEVENT_TIME: |
670 |
if (timercmp(&ev->when, &now, <=)) |
693 |
if (timercmp(&ev->when, &now, <=)) |
671 |
ev->flags |= PEVENT_OCCURRED; |
694 |
PEVENT_SET_OCCURRED(ctx, ev); |
672 |
break; |
695 |
break; |
673 |
default: |
696 |
default: |
674 |
break; |
697 |
break; |
675 |
} |
698 |
} |
676 |
} |
699 |
} |
677 |
|
700 |
|
678 |
/* If we were intentionally woken up, read the wakeup byte */ |
|
|
679 |
if (ctx->notified) { |
680 |
DBG(PEVENT, "ctx %p thread was notified", ctx); |
681 |
(void)read(ctx->pipe[0], &pevent_byte, 1); |
682 |
ctx->notified = 0; |
683 |
} |
684 |
|
685 |
/* Service all events that are marked as having occurred */ |
701 |
/* Service all events that are marked as having occurred */ |
686 |
while (1) { |
702 |
while (1) { |
687 |
|
703 |
|
688 |
/* Find next event that needs service XXX this is O(n^2) XXX */ |
704 |
/* Find next event that needs service */ |
689 |
TAILQ_FOREACH(ev, &ctx->events, next) { |
705 |
ev = TAILQ_FIRST(&ctx->events); |
690 |
if ((ev->flags & PEVENT_OCCURRED) != 0) |
706 |
if (ev == NULL || (ev->flags & PEVENT_OCCURRED) == 0) |
691 |
break; |
|
|
692 |
} |
693 |
if (ev == NULL) |
694 |
break; |
707 |
break; |
695 |
DBG(PEVENT, "ctx %p thread servicing ev %p", ctx, ev); |
708 |
DBG(PEVENT, "ctx %p thread servicing ev %p", ctx, ev); |
696 |
|
709 |
|