1 /* $OpenBSD: event.c,v 1.28 2014/04/03 11:27:02 eric Exp $ */ 2 3 /* 4 * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #ifdef WIN32 34 #define WIN32_LEAN_AND_MEAN 35 #include <windows.h> 36 #undef WIN32_LEAN_AND_MEAN 37 #endif 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 #ifdef HAVE_SYS_TIME_H 41 #include <sys/time.h> 42 #else 43 #include <sys/_libevent_time.h> 44 #endif 45 #include <sys/queue.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #ifndef WIN32 49 #include <unistd.h> 50 #endif 51 #include <errno.h> 52 #include <signal.h> 53 #include <string.h> 54 #include <assert.h> 55 #include <time.h> 56 #include <netdb.h> 57 #include <asr.h> 58 59 #include "event.h" 60 #include "event-internal.h" 61 #include "evutil.h" 62 #include "log.h" 63 64 #ifdef HAVE_EVENT_PORTS 65 extern const struct eventop evportops; 66 #endif 67 #ifdef HAVE_SELECT 68 extern const struct eventop selectops; 69 #endif 70 #ifdef HAVE_POLL 71 extern const struct eventop pollops; 72 #endif 73 #ifdef HAVE_EPOLL 74 extern const struct eventop epollops; 75 #endif 76 #ifdef HAVE_WORKING_KQUEUE 77 extern const struct eventop kqops; 78 #endif 79 #ifdef HAVE_DEVPOLL 80 extern const struct eventop devpollops; 81 #endif 82 #ifdef WIN32 83 extern const struct eventop win32ops; 84 #endif 85 86 /* In order of preference */ 87 static const struct eventop *eventops[] = { 88 #ifdef HAVE_EVENT_PORTS 89 &evportops, 90 #endif 91 #ifdef HAVE_WORKING_KQUEUE 92 &kqops, 93 #endif 94 #ifdef HAVE_EPOLL 95 &epollops, 96 #endif 97 #ifdef HAVE_DEVPOLL 98 &devpollops, 99 #endif 100 #ifdef HAVE_POLL 101 &pollops, 102 #endif 103 #ifdef HAVE_SELECT 104 &selectops, 105 #endif 106 #ifdef WIN32 107 &win32ops, 108 #endif 109 NULL 110 }; 111 112 /* Global state */ 113 struct event_base *current_base = NULL; 114 extern struct event_base *evsignal_base; 115 static int use_monotonic; 116 117 /* Handle signals - This is a deprecated interface */ 118 int (*event_sigcb)(void); /* Signal callback when gotsig is set */ 119 volatile sig_atomic_t event_gotsig; /* Set in signal handler */ 120 121 /* Prototypes */ 122 static void event_queue_insert(struct event_base *, struct event *, int); 123 static void event_queue_remove(struct event_base *, struct event *, int); 124 static int event_haveevents(struct event_base *); 125 126 static void event_process_active(struct event_base *); 127 128 static int timeout_next(struct event_base *, struct timeval **); 129 static void timeout_process(struct event_base *); 130 static void timeout_correct(struct event_base *, struct timeval *); 131 132 static void 133 detect_monotonic(void) 134 { 135 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) 136 struct timespec ts; 137 138 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 139 use_monotonic = 1; 140 #endif 141 } 142 143 static int 144 gettime(struct event_base *base, struct timeval *tp) 145 { 146 if (base->tv_cache.tv_sec) { 147 *tp = base->tv_cache; 148 return (0); 149 } 150 151 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) 152 if (use_monotonic) { 153 struct timespec ts; 154 155 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) 156 return (-1); 157 158 tp->tv_sec = ts.tv_sec; 159 tp->tv_usec = ts.tv_nsec / 1000; 160 return (0); 161 } 162 #endif 163 164 return (evutil_gettimeofday(tp, NULL)); 165 } 166 167 struct event_base * 168 event_init(void) 169 { 170 struct event_base *base = event_base_new(); 171 172 if (base != NULL) 173 current_base = base; 174 175 return (base); 176 } 177 178 struct event_base * 179 event_base_new(void) 180 { 181 int i; 182 struct event_base *base; 183 184 if ((base = calloc(1, sizeof(struct event_base))) == NULL) 185 event_err(1, "%s: calloc", __func__); 186 187 event_sigcb = NULL; 188 event_gotsig = 0; 189 190 detect_monotonic(); 191 gettime(base, &base->event_tv); 192 193 min_heap_ctor(&base->timeheap); 194 TAILQ_INIT(&base->eventqueue); 195 base->sig.ev_signal_pair[0] = -1; 196 base->sig.ev_signal_pair[1] = -1; 197 198 base->evbase = NULL; 199 for (i = 0; eventops[i] && !base->evbase; i++) { 200 base->evsel = eventops[i]; 201 202 base->evbase = base->evsel->init(base); 203 } 204 205 if (base->evbase == NULL) 206 event_errx(1, "%s: no event mechanism available", __func__); 207 208 if (evutil_getenv("EVENT_SHOW_METHOD")) 209 event_msgx("libevent using: %s\n", 210 base->evsel->name); 211 212 /* allocate a single active event queue */ 213 event_base_priority_init(base, 1); 214 215 return (base); 216 } 217 218 void 219 event_base_free(struct event_base *base) 220 { 221 int i, n_deleted=0; 222 struct event *ev; 223 224 if (base == NULL && current_base) 225 base = current_base; 226 if (base == current_base) 227 current_base = NULL; 228 229 /* XXX(niels) - check for internal events first */ 230 assert(base); 231 /* Delete all non-internal events. */ 232 for (ev = TAILQ_FIRST(&base->eventqueue); ev; ) { 233 struct event *next = TAILQ_NEXT(ev, ev_next); 234 if (!(ev->ev_flags & EVLIST_INTERNAL)) { 235 event_del(ev); 236 ++n_deleted; 237 } 238 ev = next; 239 } 240 while ((ev = min_heap_top(&base->timeheap)) != NULL) { 241 event_del(ev); 242 ++n_deleted; 243 } 244 245 for (i = 0; i < base->nactivequeues; ++i) { 246 for (ev = TAILQ_FIRST(base->activequeues[i]); ev; ) { 247 struct event *next = TAILQ_NEXT(ev, ev_active_next); 248 if (!(ev->ev_flags & EVLIST_INTERNAL)) { 249 event_del(ev); 250 ++n_deleted; 251 } 252 ev = next; 253 } 254 } 255 256 if (n_deleted) 257 event_debug(("%s: %d events were still set in base", 258 __func__, n_deleted)); 259 260 if (base->evsel->dealloc != NULL) 261 base->evsel->dealloc(base, base->evbase); 262 263 for (i = 0; i < base->nactivequeues; ++i) 264 assert(TAILQ_EMPTY(base->activequeues[i])); 265 266 assert(min_heap_empty(&base->timeheap)); 267 min_heap_dtor(&base->timeheap); 268 269 for (i = 0; i < base->nactivequeues; ++i) 270 free(base->activequeues[i]); 271 free(base->activequeues); 272 273 assert(TAILQ_EMPTY(&base->eventqueue)); 274 275 free(base); 276 } 277 278 /* reinitialized the event base after a fork */ 279 int 280 event_reinit(struct event_base *base) 281 { 282 const struct eventop *evsel = base->evsel; 283 void *evbase = base->evbase; 284 int res = 0; 285 struct event *ev; 286 287 #if 0 288 /* Right now, reinit always takes effect, since even if the 289 backend doesn't require it, the signal socketpair code does. 290 */ 291 /* check if this event mechanism requires reinit */ 292 if (!evsel->need_reinit) 293 return (0); 294 #endif 295 296 /* prevent internal delete */ 297 if (base->sig.ev_signal_added) { 298 /* we cannot call event_del here because the base has 299 * not been reinitialized yet. */ 300 event_queue_remove(base, &base->sig.ev_signal, 301 EVLIST_INSERTED); 302 if (base->sig.ev_signal.ev_flags & EVLIST_ACTIVE) 303 event_queue_remove(base, &base->sig.ev_signal, 304 EVLIST_ACTIVE); 305 base->sig.ev_signal_added = 0; 306 } 307 308 if (base->evsel->dealloc != NULL) 309 base->evsel->dealloc(base, base->evbase); 310 evbase = base->evbase = evsel->init(base); 311 if (base->evbase == NULL) 312 event_errx(1, "%s: could not reinitialize event mechanism", 313 __func__); 314 315 TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { 316 if (evsel->add(evbase, ev) == -1) 317 res = -1; 318 } 319 320 return (res); 321 } 322 323 int 324 event_priority_init(int npriorities) 325 { 326 return event_base_priority_init(current_base, npriorities); 327 } 328 329 int 330 event_base_priority_init(struct event_base *base, int npriorities) 331 { 332 int i; 333 334 if (base->event_count_active) 335 return (-1); 336 337 if (npriorities == base->nactivequeues) 338 return (0); 339 340 if (base->nactivequeues) { 341 for (i = 0; i < base->nactivequeues; ++i) { 342 free(base->activequeues[i]); 343 } 344 free(base->activequeues); 345 } 346 347 /* Allocate our priority queues */ 348 base->nactivequeues = npriorities; 349 base->activequeues = (struct event_list **) 350 calloc(base->nactivequeues, sizeof(struct event_list *)); 351 if (base->activequeues == NULL) 352 event_err(1, "%s: calloc", __func__); 353 354 for (i = 0; i < base->nactivequeues; ++i) { 355 base->activequeues[i] = malloc(sizeof(struct event_list)); 356 if (base->activequeues[i] == NULL) 357 event_err(1, "%s: malloc", __func__); 358 TAILQ_INIT(base->activequeues[i]); 359 } 360 361 return (0); 362 } 363 364 int 365 event_haveevents(struct event_base *base) 366 { 367 return (base->event_count > 0); 368 } 369 370 /* 371 * Active events are stored in priority queues. Lower priorities are always 372 * process before higher priorities. Low priority events can starve high 373 * priority ones. 374 */ 375 376 static void 377 event_process_active(struct event_base *base) 378 { 379 struct event *ev; 380 struct event_list *activeq = NULL; 381 int i; 382 short ncalls; 383 384 for (i = 0; i < base->nactivequeues; ++i) { 385 if (TAILQ_FIRST(base->activequeues[i]) != NULL) { 386 activeq = base->activequeues[i]; 387 break; 388 } 389 } 390 391 assert(activeq != NULL); 392 393 for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) { 394 if (ev->ev_events & EV_PERSIST) 395 event_queue_remove(base, ev, EVLIST_ACTIVE); 396 else 397 event_del(ev); 398 399 /* Allows deletes to work */ 400 ncalls = ev->ev_ncalls; 401 ev->ev_pncalls = &ncalls; 402 while (ncalls) { 403 ncalls--; 404 ev->ev_ncalls = ncalls; 405 (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg); 406 if (event_gotsig || base->event_break) 407 return; 408 } 409 } 410 } 411 412 /* 413 * Wait continously for events. We exit only if no events are left. 414 */ 415 416 int 417 event_dispatch(void) 418 { 419 return (event_loop(0)); 420 } 421 422 int 423 event_base_dispatch(struct event_base *event_base) 424 { 425 return (event_base_loop(event_base, 0)); 426 } 427 428 const char * 429 event_base_get_method(struct event_base *base) 430 { 431 assert(base); 432 return (base->evsel->name); 433 } 434 435 static void 436 event_loopexit_cb(int fd, short what, void *arg) 437 { 438 struct event_base *base = arg; 439 base->event_gotterm = 1; 440 } 441 442 /* not thread safe */ 443 int 444 event_loopexit(const struct timeval *tv) 445 { 446 return (event_once(-1, EV_TIMEOUT, event_loopexit_cb, 447 current_base, tv)); 448 } 449 450 int 451 event_base_loopexit(struct event_base *event_base, const struct timeval *tv) 452 { 453 return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb, 454 event_base, tv)); 455 } 456 457 /* not thread safe */ 458 int 459 event_loopbreak(void) 460 { 461 return (event_base_loopbreak(current_base)); 462 } 463 464 int 465 event_base_loopbreak(struct event_base *event_base) 466 { 467 if (event_base == NULL) 468 return (-1); 469 470 event_base->event_break = 1; 471 return (0); 472 } 473 474 475 476 /* not thread safe */ 477 478 int 479 event_loop(int flags) 480 { 481 return event_base_loop(current_base, flags); 482 } 483 484 int 485 event_base_loop(struct event_base *base, int flags) 486 { 487 const struct eventop *evsel = base->evsel; 488 void *evbase = base->evbase; 489 struct timeval tv; 490 struct timeval *tv_p; 491 int res, done; 492 493 /* clear time cache */ 494 base->tv_cache.tv_sec = 0; 495 496 if (base->sig.ev_signal_added) 497 evsignal_base = base; 498 done = 0; 499 while (!done) { 500 /* Terminate the loop if we have been asked to */ 501 if (base->event_gotterm) { 502 base->event_gotterm = 0; 503 break; 504 } 505 506 if (base->event_break) { 507 base->event_break = 0; 508 break; 509 } 510 511 /* You cannot use this interface for multi-threaded apps */ 512 while (event_gotsig) { 513 event_gotsig = 0; 514 if (event_sigcb) { 515 res = (*event_sigcb)(); 516 if (res == -1) { 517 errno = EINTR; 518 return (-1); 519 } 520 } 521 } 522 523 timeout_correct(base, &tv); 524 525 tv_p = &tv; 526 if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) { 527 timeout_next(base, &tv_p); 528 } else { 529 /* 530 * if we have active events, we just poll new events 531 * without waiting. 532 */ 533 evutil_timerclear(&tv); 534 } 535 536 /* If we have no events, we just exit */ 537 if (!event_haveevents(base)) { 538 event_debug(("%s: no events registered.", __func__)); 539 return (1); 540 } 541 542 /* update last old time */ 543 gettime(base, &base->event_tv); 544 545 /* clear time cache */ 546 base->tv_cache.tv_sec = 0; 547 548 res = evsel->dispatch(base, evbase, tv_p); 549 550 if (res == -1) 551 return (-1); 552 gettime(base, &base->tv_cache); 553 554 timeout_process(base); 555 556 if (base->event_count_active) { 557 event_process_active(base); 558 if (!base->event_count_active && (flags & EVLOOP_ONCE)) 559 done = 1; 560 } else if (flags & EVLOOP_NONBLOCK) 561 done = 1; 562 } 563 564 /* clear time cache */ 565 base->tv_cache.tv_sec = 0; 566 567 event_debug(("%s: asked to terminate loop.", __func__)); 568 return (0); 569 } 570 571 /* Sets up an event for processing once */ 572 573 struct event_once { 574 struct event ev; 575 576 void (*cb)(int, short, void *); 577 void *arg; 578 }; 579 580 /* One-time callback, it deletes itself */ 581 582 static void 583 event_once_cb(int fd, short events, void *arg) 584 { 585 struct event_once *eonce = arg; 586 587 (*eonce->cb)(fd, events, eonce->arg); 588 free(eonce); 589 } 590 591 /* not threadsafe, event scheduled once. */ 592 int 593 event_once(int fd, short events, 594 void (*callback)(int, short, void *), void *arg, const struct timeval *tv) 595 { 596 return event_base_once(current_base, fd, events, callback, arg, tv); 597 } 598 599 /* Schedules an event once */ 600 int 601 event_base_once(struct event_base *base, int fd, short events, 602 void (*callback)(int, short, void *), void *arg, const struct timeval *tv) 603 { 604 struct event_once *eonce; 605 struct timeval etv; 606 int res; 607 608 /* We cannot support signals that just fire once */ 609 if (events & EV_SIGNAL) 610 return (-1); 611 612 if ((eonce = calloc(1, sizeof(struct event_once))) == NULL) 613 return (-1); 614 615 eonce->cb = callback; 616 eonce->arg = arg; 617 618 if (events == EV_TIMEOUT) { 619 if (tv == NULL) { 620 evutil_timerclear(&etv); 621 tv = &etv; 622 } 623 624 evtimer_set(&eonce->ev, event_once_cb, eonce); 625 } else if (events & (EV_READ|EV_WRITE)) { 626 events &= EV_READ|EV_WRITE; 627 628 event_set(&eonce->ev, fd, events, event_once_cb, eonce); 629 } else { 630 /* Bad event combination */ 631 free(eonce); 632 return (-1); 633 } 634 635 res = event_base_set(base, &eonce->ev); 636 if (res == 0) 637 res = event_add(&eonce->ev, tv); 638 if (res != 0) { 639 free(eonce); 640 return (res); 641 } 642 643 return (0); 644 } 645 646 void 647 event_set(struct event *ev, int fd, short events, 648 void (*callback)(int, short, void *), void *arg) 649 { 650 /* Take the current base - caller needs to set the real base later */ 651 ev->ev_base = current_base; 652 653 ev->ev_callback = callback; 654 ev->ev_arg = arg; 655 ev->ev_fd = fd; 656 ev->ev_events = events; 657 ev->ev_res = 0; 658 ev->ev_flags = EVLIST_INIT; 659 ev->ev_ncalls = 0; 660 ev->ev_pncalls = NULL; 661 662 min_heap_elem_init(ev); 663 664 /* by default, we put new events into the middle priority */ 665 if(current_base) 666 ev->ev_pri = current_base->nactivequeues/2; 667 } 668 669 int 670 event_base_set(struct event_base *base, struct event *ev) 671 { 672 /* Only innocent events may be assigned to a different base */ 673 if (ev->ev_flags != EVLIST_INIT) 674 return (-1); 675 676 ev->ev_base = base; 677 ev->ev_pri = base->nactivequeues/2; 678 679 return (0); 680 } 681 682 /* 683 * Set's the priority of an event - if an event is already scheduled 684 * changing the priority is going to fail. 685 */ 686 687 int 688 event_priority_set(struct event *ev, int pri) 689 { 690 if (ev->ev_flags & EVLIST_ACTIVE) 691 return (-1); 692 if (pri < 0 || pri >= ev->ev_base->nactivequeues) 693 return (-1); 694 695 ev->ev_pri = pri; 696 697 return (0); 698 } 699 700 /* 701 * Checks if a specific event is pending or scheduled. 702 */ 703 704 int 705 event_pending(struct event *ev, short event, struct timeval *tv) 706 { 707 struct timeval now, res; 708 int flags = 0; 709 710 if (ev->ev_flags & EVLIST_INSERTED) 711 flags |= (ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)); 712 if (ev->ev_flags & EVLIST_ACTIVE) 713 flags |= ev->ev_res; 714 if (ev->ev_flags & EVLIST_TIMEOUT) 715 flags |= EV_TIMEOUT; 716 717 event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL); 718 719 /* See if there is a timeout that we should report */ 720 if (tv != NULL && (flags & event & EV_TIMEOUT)) { 721 gettime(ev->ev_base, &now); 722 evutil_timersub(&ev->ev_timeout, &now, &res); 723 /* correctly remap to real time */ 724 evutil_gettimeofday(&now, NULL); 725 evutil_timeradd(&now, &res, tv); 726 } 727 728 return (flags & event); 729 } 730 731 int 732 event_add(struct event *ev, const struct timeval *tv) 733 { 734 struct event_base *base = ev->ev_base; 735 const struct eventop *evsel = base->evsel; 736 void *evbase = base->evbase; 737 int res = 0; 738 739 event_debug(( 740 "event_add: event: %p, %s%s%scall %p", 741 ev, 742 ev->ev_events & EV_READ ? "EV_READ " : " ", 743 ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", 744 tv ? "EV_TIMEOUT " : " ", 745 ev->ev_callback)); 746 747 assert(!(ev->ev_flags & ~EVLIST_ALL)); 748 749 /* 750 * prepare for timeout insertion further below, if we get a 751 * failure on any step, we should not change any state. 752 */ 753 if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) { 754 if (min_heap_reserve(&base->timeheap, 755 1 + min_heap_size(&base->timeheap)) == -1) 756 return (-1); /* ENOMEM == errno */ 757 } 758 759 if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) && 760 !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { 761 res = evsel->add(evbase, ev); 762 if (res != -1) 763 event_queue_insert(base, ev, EVLIST_INSERTED); 764 } 765 766 /* 767 * we should change the timout state only if the previous event 768 * addition succeeded. 769 */ 770 if (res != -1 && tv != NULL) { 771 struct timeval now; 772 773 /* 774 * we already reserved memory above for the case where we 775 * are not replacing an exisiting timeout. 776 */ 777 if (ev->ev_flags & EVLIST_TIMEOUT) 778 event_queue_remove(base, ev, EVLIST_TIMEOUT); 779 780 /* Check if it is active due to a timeout. Rescheduling 781 * this timeout before the callback can be executed 782 * removes it from the active list. */ 783 if ((ev->ev_flags & EVLIST_ACTIVE) && 784 (ev->ev_res & EV_TIMEOUT)) { 785 /* See if we are just active executing this 786 * event in a loop 787 */ 788 if (ev->ev_ncalls && ev->ev_pncalls) { 789 /* Abort loop */ 790 *ev->ev_pncalls = 0; 791 } 792 793 event_queue_remove(base, ev, EVLIST_ACTIVE); 794 } 795 796 gettime(base, &now); 797 evutil_timeradd(&now, tv, &ev->ev_timeout); 798 799 event_debug(( 800 "event_add: timeout in %lld seconds, call %p", 801 (long long)tv->tv_sec, ev->ev_callback)); 802 803 event_queue_insert(base, ev, EVLIST_TIMEOUT); 804 } 805 806 return (res); 807 } 808 809 int 810 event_del(struct event *ev) 811 { 812 struct event_base *base; 813 const struct eventop *evsel; 814 void *evbase; 815 816 event_debug(("event_del: %p, callback %p", 817 ev, ev->ev_callback)); 818 819 /* An event without a base has not been added */ 820 if (ev->ev_base == NULL) 821 return (-1); 822 823 base = ev->ev_base; 824 evsel = base->evsel; 825 evbase = base->evbase; 826 827 assert(!(ev->ev_flags & ~EVLIST_ALL)); 828 829 /* See if we are just active executing this event in a loop */ 830 if (ev->ev_ncalls && ev->ev_pncalls) { 831 /* Abort loop */ 832 *ev->ev_pncalls = 0; 833 } 834 835 if (ev->ev_flags & EVLIST_TIMEOUT) 836 event_queue_remove(base, ev, EVLIST_TIMEOUT); 837 838 if (ev->ev_flags & EVLIST_ACTIVE) 839 event_queue_remove(base, ev, EVLIST_ACTIVE); 840 841 if (ev->ev_flags & EVLIST_INSERTED) { 842 event_queue_remove(base, ev, EVLIST_INSERTED); 843 return (evsel->del(evbase, ev)); 844 } 845 846 return (0); 847 } 848 849 void 850 event_active(struct event *ev, int res, short ncalls) 851 { 852 /* We get different kinds of events, add them together */ 853 if (ev->ev_flags & EVLIST_ACTIVE) { 854 ev->ev_res |= res; 855 return; 856 } 857 858 ev->ev_res = res; 859 ev->ev_ncalls = ncalls; 860 ev->ev_pncalls = NULL; 861 event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE); 862 } 863 864 static int 865 timeout_next(struct event_base *base, struct timeval **tv_p) 866 { 867 struct timeval now; 868 struct event *ev; 869 struct timeval *tv = *tv_p; 870 871 if ((ev = min_heap_top(&base->timeheap)) == NULL) { 872 /* if no time-based events are active wait for I/O */ 873 *tv_p = NULL; 874 return (0); 875 } 876 877 if (gettime(base, &now) == -1) 878 return (-1); 879 880 if (evutil_timercmp(&ev->ev_timeout, &now, <=)) { 881 evutil_timerclear(tv); 882 return (0); 883 } 884 885 evutil_timersub(&ev->ev_timeout, &now, tv); 886 887 assert(tv->tv_sec >= 0); 888 assert(tv->tv_usec >= 0); 889 890 event_debug(("timeout_next: in %lld seconds", (long long)tv->tv_sec)); 891 return (0); 892 } 893 894 /* 895 * Determines if the time is running backwards by comparing the current 896 * time against the last time we checked. Not needed when using clock 897 * monotonic. 898 */ 899 900 static void 901 timeout_correct(struct event_base *base, struct timeval *tv) 902 { 903 struct event **pev; 904 unsigned int size; 905 struct timeval off; 906 907 if (use_monotonic) 908 return; 909 910 /* Check if time is running backwards */ 911 gettime(base, tv); 912 if (evutil_timercmp(tv, &base->event_tv, >=)) { 913 base->event_tv = *tv; 914 return; 915 } 916 917 event_debug(("%s: time is running backwards, corrected", 918 __func__)); 919 evutil_timersub(&base->event_tv, tv, &off); 920 921 /* 922 * We can modify the key element of the node without destroying 923 * the key, beause we apply it to all in the right order. 924 */ 925 pev = base->timeheap.p; 926 size = base->timeheap.n; 927 for (; size-- > 0; ++pev) { 928 struct timeval *ev_tv = &(**pev).ev_timeout; 929 evutil_timersub(ev_tv, &off, ev_tv); 930 } 931 /* Now remember what the new time turned out to be. */ 932 base->event_tv = *tv; 933 } 934 935 void 936 timeout_process(struct event_base *base) 937 { 938 struct timeval now; 939 struct event *ev; 940 941 if (min_heap_empty(&base->timeheap)) 942 return; 943 944 gettime(base, &now); 945 946 while ((ev = min_heap_top(&base->timeheap))) { 947 if (evutil_timercmp(&ev->ev_timeout, &now, >)) 948 break; 949 950 /* delete this event from the I/O queues */ 951 event_del(ev); 952 953 event_debug(("timeout_process: call %p", 954 ev->ev_callback)); 955 event_active(ev, EV_TIMEOUT, 1); 956 } 957 } 958 959 void 960 event_queue_remove(struct event_base *base, struct event *ev, int queue) 961 { 962 if (!(ev->ev_flags & queue)) 963 event_errx(1, "%s: %p(fd %d) not on queue %x", __func__, 964 ev, ev->ev_fd, queue); 965 966 if (~ev->ev_flags & EVLIST_INTERNAL) 967 base->event_count--; 968 969 ev->ev_flags &= ~queue; 970 switch (queue) { 971 case EVLIST_INSERTED: 972 TAILQ_REMOVE(&base->eventqueue, ev, ev_next); 973 break; 974 case EVLIST_ACTIVE: 975 base->event_count_active--; 976 TAILQ_REMOVE(base->activequeues[ev->ev_pri], 977 ev, ev_active_next); 978 break; 979 case EVLIST_TIMEOUT: 980 min_heap_erase(&base->timeheap, ev); 981 break; 982 default: 983 event_errx(1, "%s: unknown queue %x", __func__, queue); 984 } 985 } 986 987 void 988 event_queue_insert(struct event_base *base, struct event *ev, int queue) 989 { 990 if (ev->ev_flags & queue) { 991 /* Double insertion is possible for active events */ 992 if (queue & EVLIST_ACTIVE) 993 return; 994 995 event_errx(1, "%s: %p(fd %d) already on queue %x", __func__, 996 ev, ev->ev_fd, queue); 997 } 998 999 if (~ev->ev_flags & EVLIST_INTERNAL) 1000 base->event_count++; 1001 1002 ev->ev_flags |= queue; 1003 switch (queue) { 1004 case EVLIST_INSERTED: 1005 TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next); 1006 break; 1007 case EVLIST_ACTIVE: 1008 base->event_count_active++; 1009 TAILQ_INSERT_TAIL(base->activequeues[ev->ev_pri], 1010 ev,ev_active_next); 1011 break; 1012 case EVLIST_TIMEOUT: { 1013 min_heap_push(&base->timeheap, ev); 1014 break; 1015 } 1016 default: 1017 event_errx(1, "%s: unknown queue %x", __func__, queue); 1018 } 1019 } 1020 1021 /* Functions for debugging */ 1022 1023 const char * 1024 event_get_version(void) 1025 { 1026 return (_EVENT_VERSION); 1027 } 1028 1029 /* 1030 * No thread-safe interface needed - the information should be the same 1031 * for all threads. 1032 */ 1033 1034 const char * 1035 event_get_method(void) 1036 { 1037 return (current_base->evsel->name); 1038 } 1039 1040 1041 /* 1042 * Libevent glue for ASR. 1043 */ 1044 struct event_asr { 1045 struct event ev; 1046 struct asr_query *async; 1047 void (*cb)(struct asr_result *, void *); 1048 void *arg; 1049 }; 1050 1051 static void 1052 event_asr_dispatch(int fd __attribute__((__unused__)), 1053 short ev __attribute__((__unused__)), void *arg) 1054 { 1055 struct event_asr *eva = arg; 1056 struct asr_result ar; 1057 struct timeval tv; 1058 1059 event_del(&eva->ev); 1060 1061 if (asr_run(eva->async, &ar)) { 1062 eva->cb(&ar, eva->arg); 1063 free(eva); 1064 } else { 1065 event_set(&eva->ev, ar.ar_fd, 1066 ar.ar_cond == ASR_WANT_READ ? EV_READ : EV_WRITE, 1067 event_asr_dispatch, eva); 1068 tv.tv_sec = ar.ar_timeout / 1000; 1069 tv.tv_usec = (ar.ar_timeout % 1000) * 1000; 1070 event_add(&eva->ev, &tv); 1071 } 1072 } 1073 1074 struct event_asr * 1075 event_asr_run(struct asr_query *async, void (*cb)(struct asr_result *, void *), 1076 void *arg) 1077 { 1078 struct event_asr *eva; 1079 struct timeval tv; 1080 1081 eva = calloc(1, sizeof *eva); 1082 if (eva == NULL) 1083 return (NULL); 1084 eva->async = async; 1085 eva->cb = cb; 1086 eva->arg = arg; 1087 tv.tv_sec = 0; 1088 tv.tv_usec = 0; 1089 evtimer_set(&eva->ev, event_asr_dispatch, eva); 1090 evtimer_add(&eva->ev, &tv); 1091 return (eva); 1092 } 1093 1094 void 1095 event_asr_abort(struct event_asr *eva) 1096 { 1097 asr_abort(eva->async); 1098 event_del(&eva->ev); 1099 free(eva); 1100 } 1101