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