1 /* 2 * Event loop based on select() loop 3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <assert.h> 11 12 #include "common.h" 13 #include "trace.h" 14 #include "list.h" 15 #include "eloop.h" 16 17 #if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_EPOLL) 18 #error Do not define both of poll and epoll 19 #endif 20 21 #if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_KQUEUE) 22 #error Do not define both of poll and kqueue 23 #endif 24 25 #if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL) && \ 26 !defined(CONFIG_ELOOP_KQUEUE) 27 #define CONFIG_ELOOP_SELECT 28 #endif 29 30 #ifdef CONFIG_ELOOP_POLL 31 #include <poll.h> 32 #endif /* CONFIG_ELOOP_POLL */ 33 34 #ifdef CONFIG_ELOOP_EPOLL 35 #include <sys/epoll.h> 36 #endif /* CONFIG_ELOOP_EPOLL */ 37 38 #ifdef CONFIG_ELOOP_KQUEUE 39 #include <sys/event.h> 40 #endif /* CONFIG_ELOOP_KQUEUE */ 41 42 struct eloop_sock { 43 int sock; 44 void *eloop_data; 45 void *user_data; 46 eloop_sock_handler handler; 47 WPA_TRACE_REF(eloop); 48 WPA_TRACE_REF(user); 49 WPA_TRACE_INFO 50 }; 51 52 struct eloop_timeout { 53 struct dl_list list; 54 struct os_reltime time; 55 void *eloop_data; 56 void *user_data; 57 eloop_timeout_handler handler; 58 WPA_TRACE_REF(eloop); 59 WPA_TRACE_REF(user); 60 WPA_TRACE_INFO 61 }; 62 63 struct eloop_signal { 64 int sig; 65 void *user_data; 66 eloop_signal_handler handler; 67 int signaled; 68 }; 69 70 struct eloop_sock_table { 71 int count; 72 struct eloop_sock *table; 73 eloop_event_type type; 74 int changed; 75 }; 76 77 struct eloop_data { 78 int max_sock; 79 80 int count; /* sum of all table counts */ 81 #ifdef CONFIG_ELOOP_POLL 82 int max_pollfd_map; /* number of pollfds_map currently allocated */ 83 int max_poll_fds; /* number of pollfds currently allocated */ 84 struct pollfd *pollfds; 85 struct pollfd **pollfds_map; 86 #endif /* CONFIG_ELOOP_POLL */ 87 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 88 int max_fd; 89 struct eloop_sock *fd_table; 90 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 91 #ifdef CONFIG_ELOOP_EPOLL 92 int epollfd; 93 int epoll_max_event_num; 94 struct epoll_event *epoll_events; 95 #endif /* CONFIG_ELOOP_EPOLL */ 96 #ifdef CONFIG_ELOOP_KQUEUE 97 int kqueuefd; 98 int kqueue_nevents; 99 struct kevent *kqueue_events; 100 #endif /* CONFIG_ELOOP_KQUEUE */ 101 struct eloop_sock_table readers; 102 struct eloop_sock_table writers; 103 struct eloop_sock_table exceptions; 104 105 struct dl_list timeout; 106 107 int signal_count; 108 struct eloop_signal *signals; 109 int signaled; 110 int pending_terminate; 111 112 int terminate; 113 }; 114 115 static struct eloop_data eloop; 116 117 118 #ifdef WPA_TRACE 119 120 static void eloop_sigsegv_handler(int sig) 121 { 122 wpa_trace_show("eloop SIGSEGV"); 123 abort(); 124 } 125 126 static void eloop_trace_sock_add_ref(struct eloop_sock_table *table) 127 { 128 int i; 129 if (table == NULL || table->table == NULL) 130 return; 131 for (i = 0; i < table->count; i++) { 132 wpa_trace_add_ref(&table->table[i], eloop, 133 table->table[i].eloop_data); 134 wpa_trace_add_ref(&table->table[i], user, 135 table->table[i].user_data); 136 } 137 } 138 139 140 static void eloop_trace_sock_remove_ref(struct eloop_sock_table *table) 141 { 142 int i; 143 if (table == NULL || table->table == NULL) 144 return; 145 for (i = 0; i < table->count; i++) { 146 wpa_trace_remove_ref(&table->table[i], eloop, 147 table->table[i].eloop_data); 148 wpa_trace_remove_ref(&table->table[i], user, 149 table->table[i].user_data); 150 } 151 } 152 153 #else /* WPA_TRACE */ 154 155 #define eloop_trace_sock_add_ref(table) do { } while (0) 156 #define eloop_trace_sock_remove_ref(table) do { } while (0) 157 158 #endif /* WPA_TRACE */ 159 160 161 int eloop_init(void) 162 { 163 os_memset(&eloop, 0, sizeof(eloop)); 164 dl_list_init(&eloop.timeout); 165 #ifdef CONFIG_ELOOP_EPOLL 166 eloop.epollfd = epoll_create1(0); 167 if (eloop.epollfd < 0) { 168 wpa_printf(MSG_ERROR, "%s: epoll_create1 failed. %s", 169 __func__, strerror(errno)); 170 return -1; 171 } 172 #endif /* CONFIG_ELOOP_EPOLL */ 173 #ifdef CONFIG_ELOOP_KQUEUE 174 eloop.kqueuefd = kqueue(); 175 if (eloop.kqueuefd < 0) { 176 wpa_printf(MSG_ERROR, "%s: kqueue failed: %s", 177 __func__, strerror(errno)); 178 return -1; 179 } 180 #endif /* CONFIG_ELOOP_KQUEUE */ 181 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 182 eloop.readers.type = EVENT_TYPE_READ; 183 eloop.writers.type = EVENT_TYPE_WRITE; 184 eloop.exceptions.type = EVENT_TYPE_EXCEPTION; 185 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 186 #ifdef WPA_TRACE 187 signal(SIGSEGV, eloop_sigsegv_handler); 188 #endif /* WPA_TRACE */ 189 return 0; 190 } 191 192 193 #ifdef CONFIG_ELOOP_EPOLL 194 static int eloop_sock_queue(int sock, eloop_event_type type) 195 { 196 struct epoll_event ev; 197 198 os_memset(&ev, 0, sizeof(ev)); 199 switch (type) { 200 case EVENT_TYPE_READ: 201 ev.events = EPOLLIN; 202 break; 203 case EVENT_TYPE_WRITE: 204 ev.events = EPOLLOUT; 205 break; 206 /* 207 * Exceptions are always checked when using epoll, but I suppose it's 208 * possible that someone registered a socket *only* for exception 209 * handling. 210 */ 211 case EVENT_TYPE_EXCEPTION: 212 ev.events = EPOLLERR | EPOLLHUP; 213 break; 214 } 215 ev.data.fd = sock; 216 if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) { 217 wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d failed: %s", 218 __func__, sock, strerror(errno)); 219 return -1; 220 } 221 return 0; 222 } 223 #endif /* CONFIG_ELOOP_EPOLL */ 224 225 226 #ifdef CONFIG_ELOOP_KQUEUE 227 228 static short event_type_kevent_filter(eloop_event_type type) 229 { 230 switch (type) { 231 case EVENT_TYPE_READ: 232 return EVFILT_READ; 233 case EVENT_TYPE_WRITE: 234 return EVFILT_WRITE; 235 default: 236 return 0; 237 } 238 } 239 240 241 static int eloop_sock_queue(int sock, eloop_event_type type) 242 { 243 struct kevent ke; 244 245 EV_SET(&ke, sock, event_type_kevent_filter(type), EV_ADD, 0, 0, 0); 246 if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) == -1) { 247 wpa_printf(MSG_ERROR, "%s: kevent(ADD) for fd=%d failed: %s", 248 __func__, sock, strerror(errno)); 249 return -1; 250 } 251 return 0; 252 } 253 254 #endif /* CONFIG_ELOOP_KQUEUE */ 255 256 257 static int eloop_sock_table_add_sock(struct eloop_sock_table *table, 258 int sock, eloop_sock_handler handler, 259 void *eloop_data, void *user_data) 260 { 261 #ifdef CONFIG_ELOOP_EPOLL 262 struct epoll_event *temp_events; 263 #endif /* CONFIG_ELOOP_EPOLL */ 264 #ifdef CONFIG_ELOOP_KQUEUE 265 struct kevent *temp_events; 266 #endif /* CONFIG_ELOOP_EPOLL */ 267 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 268 struct eloop_sock *temp_table; 269 int next; 270 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 271 struct eloop_sock *tmp; 272 int new_max_sock; 273 274 if (sock > eloop.max_sock) 275 new_max_sock = sock; 276 else 277 new_max_sock = eloop.max_sock; 278 279 if (table == NULL) 280 return -1; 281 282 #ifdef CONFIG_ELOOP_POLL 283 if (new_max_sock >= eloop.max_pollfd_map) { 284 struct pollfd **nmap; 285 nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50, 286 sizeof(struct pollfd *)); 287 if (nmap == NULL) 288 return -1; 289 290 eloop.max_pollfd_map = new_max_sock + 50; 291 eloop.pollfds_map = nmap; 292 } 293 294 if (eloop.count + 1 > eloop.max_poll_fds) { 295 struct pollfd *n; 296 int nmax = eloop.count + 1 + 50; 297 n = os_realloc_array(eloop.pollfds, nmax, 298 sizeof(struct pollfd)); 299 if (n == NULL) 300 return -1; 301 302 eloop.max_poll_fds = nmax; 303 eloop.pollfds = n; 304 } 305 #endif /* CONFIG_ELOOP_POLL */ 306 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 307 if (new_max_sock >= eloop.max_fd) { 308 next = new_max_sock + 16; 309 temp_table = os_realloc_array(eloop.fd_table, next, 310 sizeof(struct eloop_sock)); 311 if (temp_table == NULL) 312 return -1; 313 314 eloop.max_fd = next; 315 eloop.fd_table = temp_table; 316 } 317 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 318 319 #ifdef CONFIG_ELOOP_EPOLL 320 if (eloop.count + 1 > eloop.epoll_max_event_num) { 321 next = eloop.epoll_max_event_num == 0 ? 8 : 322 eloop.epoll_max_event_num * 2; 323 temp_events = os_realloc_array(eloop.epoll_events, next, 324 sizeof(struct epoll_event)); 325 if (temp_events == NULL) { 326 wpa_printf(MSG_ERROR, "%s: malloc for epoll failed: %s", 327 __func__, strerror(errno)); 328 return -1; 329 } 330 331 eloop.epoll_max_event_num = next; 332 eloop.epoll_events = temp_events; 333 } 334 #endif /* CONFIG_ELOOP_EPOLL */ 335 #ifdef CONFIG_ELOOP_KQUEUE 336 if (eloop.count + 1 > eloop.kqueue_nevents) { 337 next = eloop.kqueue_nevents == 0 ? 8 : eloop.kqueue_nevents * 2; 338 temp_events = os_malloc(next * sizeof(*temp_events)); 339 if (!temp_events) { 340 wpa_printf(MSG_ERROR, 341 "%s: malloc for kqueue failed: %s", 342 __func__, strerror(errno)); 343 return -1; 344 } 345 346 os_free(eloop.kqueue_events); 347 eloop.kqueue_events = temp_events; 348 eloop.kqueue_nevents = next; 349 } 350 #endif /* CONFIG_ELOOP_KQUEUE */ 351 352 eloop_trace_sock_remove_ref(table); 353 tmp = os_realloc_array(table->table, table->count + 1, 354 sizeof(struct eloop_sock)); 355 if (tmp == NULL) { 356 eloop_trace_sock_add_ref(table); 357 return -1; 358 } 359 360 tmp[table->count].sock = sock; 361 tmp[table->count].eloop_data = eloop_data; 362 tmp[table->count].user_data = user_data; 363 tmp[table->count].handler = handler; 364 wpa_trace_record(&tmp[table->count]); 365 table->count++; 366 table->table = tmp; 367 eloop.max_sock = new_max_sock; 368 eloop.count++; 369 table->changed = 1; 370 eloop_trace_sock_add_ref(table); 371 372 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 373 if (eloop_sock_queue(sock, table->type) < 0) 374 return -1; 375 os_memcpy(&eloop.fd_table[sock], &table->table[table->count - 1], 376 sizeof(struct eloop_sock)); 377 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 378 return 0; 379 } 380 381 382 static void eloop_sock_table_remove_sock(struct eloop_sock_table *table, 383 int sock) 384 { 385 #ifdef CONFIG_ELOOP_KQUEUE 386 struct kevent ke; 387 #endif /* CONFIG_ELOOP_KQUEUE */ 388 int i; 389 390 if (table == NULL || table->table == NULL || table->count == 0) 391 return; 392 393 for (i = 0; i < table->count; i++) { 394 if (table->table[i].sock == sock) 395 break; 396 } 397 if (i == table->count) 398 return; 399 eloop_trace_sock_remove_ref(table); 400 if (i != table->count - 1) { 401 os_memmove(&table->table[i], &table->table[i + 1], 402 (table->count - i - 1) * 403 sizeof(struct eloop_sock)); 404 } 405 table->count--; 406 eloop.count--; 407 table->changed = 1; 408 eloop_trace_sock_add_ref(table); 409 #ifdef CONFIG_ELOOP_EPOLL 410 if (epoll_ctl(eloop.epollfd, EPOLL_CTL_DEL, sock, NULL) < 0) { 411 wpa_printf(MSG_ERROR, "%s: epoll_ctl(DEL) for fd=%d failed: %s", 412 __func__, sock, strerror(errno)); 413 return; 414 } 415 os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock)); 416 #endif /* CONFIG_ELOOP_EPOLL */ 417 #ifdef CONFIG_ELOOP_KQUEUE 418 EV_SET(&ke, sock, event_type_kevent_filter(table->type), EV_DELETE, 0, 419 0, 0); 420 if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) < 0) { 421 wpa_printf(MSG_ERROR, "%s: kevent(DEL) for fd=%d failed: %s", 422 __func__, sock, strerror(errno)); 423 return; 424 } 425 os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock)); 426 #endif /* CONFIG_ELOOP_KQUEUE */ 427 } 428 429 430 #ifdef CONFIG_ELOOP_POLL 431 432 static struct pollfd * find_pollfd(struct pollfd **pollfds_map, int fd, int mx) 433 { 434 if (fd < mx && fd >= 0) 435 return pollfds_map[fd]; 436 return NULL; 437 } 438 439 440 static int eloop_sock_table_set_fds(struct eloop_sock_table *readers, 441 struct eloop_sock_table *writers, 442 struct eloop_sock_table *exceptions, 443 struct pollfd *pollfds, 444 struct pollfd **pollfds_map, 445 int max_pollfd_map) 446 { 447 int i; 448 int nxt = 0; 449 int fd; 450 struct pollfd *pfd; 451 452 /* Clear pollfd lookup map. It will be re-populated below. */ 453 os_memset(pollfds_map, 0, sizeof(struct pollfd *) * max_pollfd_map); 454 455 if (readers && readers->table) { 456 for (i = 0; i < readers->count; i++) { 457 fd = readers->table[i].sock; 458 assert(fd >= 0 && fd < max_pollfd_map); 459 pollfds[nxt].fd = fd; 460 pollfds[nxt].events = POLLIN; 461 pollfds[nxt].revents = 0; 462 pollfds_map[fd] = &(pollfds[nxt]); 463 nxt++; 464 } 465 } 466 467 if (writers && writers->table) { 468 for (i = 0; i < writers->count; i++) { 469 /* 470 * See if we already added this descriptor, update it 471 * if so. 472 */ 473 fd = writers->table[i].sock; 474 assert(fd >= 0 && fd < max_pollfd_map); 475 pfd = pollfds_map[fd]; 476 if (!pfd) { 477 pfd = &(pollfds[nxt]); 478 pfd->events = 0; 479 pfd->fd = fd; 480 pollfds[i].revents = 0; 481 pollfds_map[fd] = pfd; 482 nxt++; 483 } 484 pfd->events |= POLLOUT; 485 } 486 } 487 488 /* 489 * Exceptions are always checked when using poll, but I suppose it's 490 * possible that someone registered a socket *only* for exception 491 * handling. Set the POLLIN bit in this case. 492 */ 493 if (exceptions && exceptions->table) { 494 for (i = 0; i < exceptions->count; i++) { 495 /* 496 * See if we already added this descriptor, just use it 497 * if so. 498 */ 499 fd = exceptions->table[i].sock; 500 assert(fd >= 0 && fd < max_pollfd_map); 501 pfd = pollfds_map[fd]; 502 if (!pfd) { 503 pfd = &(pollfds[nxt]); 504 pfd->events = POLLIN; 505 pfd->fd = fd; 506 pollfds[i].revents = 0; 507 pollfds_map[fd] = pfd; 508 nxt++; 509 } 510 } 511 } 512 513 return nxt; 514 } 515 516 517 static int eloop_sock_table_dispatch_table(struct eloop_sock_table *table, 518 struct pollfd **pollfds_map, 519 int max_pollfd_map, 520 short int revents) 521 { 522 int i; 523 struct pollfd *pfd; 524 525 if (!table || !table->table) 526 return 0; 527 528 table->changed = 0; 529 for (i = 0; i < table->count; i++) { 530 pfd = find_pollfd(pollfds_map, table->table[i].sock, 531 max_pollfd_map); 532 if (!pfd) 533 continue; 534 535 if (!(pfd->revents & revents)) 536 continue; 537 538 table->table[i].handler(table->table[i].sock, 539 table->table[i].eloop_data, 540 table->table[i].user_data); 541 if (table->changed) 542 return 1; 543 } 544 545 return 0; 546 } 547 548 549 static void eloop_sock_table_dispatch(struct eloop_sock_table *readers, 550 struct eloop_sock_table *writers, 551 struct eloop_sock_table *exceptions, 552 struct pollfd **pollfds_map, 553 int max_pollfd_map) 554 { 555 if (eloop_sock_table_dispatch_table(readers, pollfds_map, 556 max_pollfd_map, POLLIN | POLLERR | 557 POLLHUP)) 558 return; /* pollfds may be invalid at this point */ 559 560 if (eloop_sock_table_dispatch_table(writers, pollfds_map, 561 max_pollfd_map, POLLOUT)) 562 return; /* pollfds may be invalid at this point */ 563 564 eloop_sock_table_dispatch_table(exceptions, pollfds_map, 565 max_pollfd_map, POLLERR | POLLHUP); 566 } 567 568 #endif /* CONFIG_ELOOP_POLL */ 569 570 #ifdef CONFIG_ELOOP_SELECT 571 572 static void eloop_sock_table_set_fds(struct eloop_sock_table *table, 573 fd_set *fds) 574 { 575 int i; 576 577 FD_ZERO(fds); 578 579 if (table->table == NULL) 580 return; 581 582 for (i = 0; i < table->count; i++) { 583 assert(table->table[i].sock >= 0); 584 FD_SET(table->table[i].sock, fds); 585 } 586 } 587 588 589 static void eloop_sock_table_dispatch(struct eloop_sock_table *table, 590 fd_set *fds) 591 { 592 int i; 593 594 if (table == NULL || table->table == NULL) 595 return; 596 597 table->changed = 0; 598 for (i = 0; i < table->count; i++) { 599 if (FD_ISSET(table->table[i].sock, fds)) { 600 table->table[i].handler(table->table[i].sock, 601 table->table[i].eloop_data, 602 table->table[i].user_data); 603 if (table->changed) 604 break; 605 } 606 } 607 } 608 609 #endif /* CONFIG_ELOOP_SELECT */ 610 611 612 #ifdef CONFIG_ELOOP_EPOLL 613 static void eloop_sock_table_dispatch(struct epoll_event *events, int nfds) 614 { 615 struct eloop_sock *table; 616 int i; 617 618 for (i = 0; i < nfds; i++) { 619 table = &eloop.fd_table[events[i].data.fd]; 620 if (table->handler == NULL) 621 continue; 622 table->handler(table->sock, table->eloop_data, 623 table->user_data); 624 if (eloop.readers.changed || 625 eloop.writers.changed || 626 eloop.exceptions.changed) 627 break; 628 } 629 } 630 #endif /* CONFIG_ELOOP_EPOLL */ 631 632 633 #ifdef CONFIG_ELOOP_KQUEUE 634 635 static void eloop_sock_table_dispatch(struct kevent *events, int nfds) 636 { 637 struct eloop_sock *table; 638 int i; 639 640 for (i = 0; i < nfds; i++) { 641 table = &eloop.fd_table[events[i].ident]; 642 if (table->handler == NULL) 643 continue; 644 table->handler(table->sock, table->eloop_data, 645 table->user_data); 646 if (eloop.readers.changed || 647 eloop.writers.changed || 648 eloop.exceptions.changed) 649 break; 650 } 651 } 652 653 654 static int eloop_sock_table_requeue(struct eloop_sock_table *table) 655 { 656 int i, r; 657 658 r = 0; 659 for (i = 0; i < table->count && table->table; i++) { 660 if (eloop_sock_queue(table->table[i].sock, table->type) == -1) 661 r = -1; 662 } 663 return r; 664 } 665 666 #endif /* CONFIG_ELOOP_KQUEUE */ 667 668 669 int eloop_sock_requeue(void) 670 { 671 int r = 0; 672 673 #ifdef CONFIG_ELOOP_KQUEUE 674 close(eloop.kqueuefd); 675 eloop.kqueuefd = kqueue(); 676 if (eloop.kqueuefd < 0) { 677 wpa_printf(MSG_ERROR, "%s: kqueue failed: %s", 678 __func__, strerror(errno)); 679 return -1; 680 } 681 682 if (eloop_sock_table_requeue(&eloop.readers) < 0) 683 r = -1; 684 if (eloop_sock_table_requeue(&eloop.writers) < 0) 685 r = -1; 686 if (eloop_sock_table_requeue(&eloop.exceptions) < 0) 687 r = -1; 688 #endif /* CONFIG_ELOOP_KQUEUE */ 689 690 return r; 691 } 692 693 694 static void eloop_sock_table_destroy(struct eloop_sock_table *table) 695 { 696 if (table) { 697 int i; 698 for (i = 0; i < table->count && table->table; i++) { 699 wpa_printf(MSG_INFO, "ELOOP: remaining socket: " 700 "sock=%d eloop_data=%p user_data=%p " 701 "handler=%p", 702 table->table[i].sock, 703 table->table[i].eloop_data, 704 table->table[i].user_data, 705 table->table[i].handler); 706 wpa_trace_dump_funcname("eloop unregistered socket " 707 "handler", 708 table->table[i].handler); 709 wpa_trace_dump("eloop sock", &table->table[i]); 710 } 711 os_free(table->table); 712 } 713 } 714 715 716 int eloop_register_read_sock(int sock, eloop_sock_handler handler, 717 void *eloop_data, void *user_data) 718 { 719 return eloop_register_sock(sock, EVENT_TYPE_READ, handler, 720 eloop_data, user_data); 721 } 722 723 724 void eloop_unregister_read_sock(int sock) 725 { 726 eloop_unregister_sock(sock, EVENT_TYPE_READ); 727 } 728 729 730 static struct eloop_sock_table *eloop_get_sock_table(eloop_event_type type) 731 { 732 switch (type) { 733 case EVENT_TYPE_READ: 734 return &eloop.readers; 735 case EVENT_TYPE_WRITE: 736 return &eloop.writers; 737 case EVENT_TYPE_EXCEPTION: 738 return &eloop.exceptions; 739 } 740 741 return NULL; 742 } 743 744 745 int eloop_register_sock(int sock, eloop_event_type type, 746 eloop_sock_handler handler, 747 void *eloop_data, void *user_data) 748 { 749 struct eloop_sock_table *table; 750 751 assert(sock >= 0); 752 table = eloop_get_sock_table(type); 753 return eloop_sock_table_add_sock(table, sock, handler, 754 eloop_data, user_data); 755 } 756 757 758 void eloop_unregister_sock(int sock, eloop_event_type type) 759 { 760 struct eloop_sock_table *table; 761 762 table = eloop_get_sock_table(type); 763 eloop_sock_table_remove_sock(table, sock); 764 } 765 766 767 int eloop_register_timeout(unsigned int secs, unsigned int usecs, 768 eloop_timeout_handler handler, 769 void *eloop_data, void *user_data) 770 { 771 struct eloop_timeout *timeout, *tmp; 772 os_time_t now_sec; 773 774 timeout = os_zalloc(sizeof(*timeout)); 775 if (timeout == NULL) 776 return -1; 777 if (os_get_reltime(&timeout->time) < 0) { 778 os_free(timeout); 779 return -1; 780 } 781 now_sec = timeout->time.sec; 782 timeout->time.sec += secs; 783 if (timeout->time.sec < now_sec) { 784 /* 785 * Integer overflow - assume long enough timeout to be assumed 786 * to be infinite, i.e., the timeout would never happen. 787 */ 788 wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to " 789 "ever happen - ignore it", secs); 790 os_free(timeout); 791 return 0; 792 } 793 timeout->time.usec += usecs; 794 while (timeout->time.usec >= 1000000) { 795 timeout->time.sec++; 796 timeout->time.usec -= 1000000; 797 } 798 timeout->eloop_data = eloop_data; 799 timeout->user_data = user_data; 800 timeout->handler = handler; 801 wpa_trace_add_ref(timeout, eloop, eloop_data); 802 wpa_trace_add_ref(timeout, user, user_data); 803 wpa_trace_record(timeout); 804 805 /* Maintain timeouts in order of increasing time */ 806 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 807 if (os_reltime_before(&timeout->time, &tmp->time)) { 808 dl_list_add(tmp->list.prev, &timeout->list); 809 return 0; 810 } 811 } 812 dl_list_add_tail(&eloop.timeout, &timeout->list); 813 814 return 0; 815 } 816 817 818 static void eloop_remove_timeout(struct eloop_timeout *timeout) 819 { 820 dl_list_del(&timeout->list); 821 wpa_trace_remove_ref(timeout, eloop, timeout->eloop_data); 822 wpa_trace_remove_ref(timeout, user, timeout->user_data); 823 os_free(timeout); 824 } 825 826 827 int eloop_cancel_timeout(eloop_timeout_handler handler, 828 void *eloop_data, void *user_data) 829 { 830 struct eloop_timeout *timeout, *prev; 831 int removed = 0; 832 833 dl_list_for_each_safe(timeout, prev, &eloop.timeout, 834 struct eloop_timeout, list) { 835 if (timeout->handler == handler && 836 (timeout->eloop_data == eloop_data || 837 eloop_data == ELOOP_ALL_CTX) && 838 (timeout->user_data == user_data || 839 user_data == ELOOP_ALL_CTX)) { 840 eloop_remove_timeout(timeout); 841 removed++; 842 } 843 } 844 845 return removed; 846 } 847 848 849 int eloop_cancel_timeout_one(eloop_timeout_handler handler, 850 void *eloop_data, void *user_data, 851 struct os_reltime *remaining) 852 { 853 struct eloop_timeout *timeout, *prev; 854 int removed = 0; 855 struct os_reltime now; 856 857 os_get_reltime(&now); 858 remaining->sec = remaining->usec = 0; 859 860 dl_list_for_each_safe(timeout, prev, &eloop.timeout, 861 struct eloop_timeout, list) { 862 if (timeout->handler == handler && 863 (timeout->eloop_data == eloop_data) && 864 (timeout->user_data == user_data)) { 865 removed = 1; 866 if (os_reltime_before(&now, &timeout->time)) 867 os_reltime_sub(&timeout->time, &now, remaining); 868 eloop_remove_timeout(timeout); 869 break; 870 } 871 } 872 return removed; 873 } 874 875 876 int eloop_is_timeout_registered(eloop_timeout_handler handler, 877 void *eloop_data, void *user_data) 878 { 879 struct eloop_timeout *tmp; 880 881 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 882 if (tmp->handler == handler && 883 tmp->eloop_data == eloop_data && 884 tmp->user_data == user_data) 885 return 1; 886 } 887 888 return 0; 889 } 890 891 892 int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, 893 eloop_timeout_handler handler, void *eloop_data, 894 void *user_data) 895 { 896 struct os_reltime now, requested, remaining; 897 struct eloop_timeout *tmp; 898 899 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 900 if (tmp->handler == handler && 901 tmp->eloop_data == eloop_data && 902 tmp->user_data == user_data) { 903 requested.sec = req_secs; 904 requested.usec = req_usecs; 905 os_get_reltime(&now); 906 os_reltime_sub(&tmp->time, &now, &remaining); 907 if (os_reltime_before(&requested, &remaining)) { 908 eloop_cancel_timeout(handler, eloop_data, 909 user_data); 910 eloop_register_timeout(requested.sec, 911 requested.usec, 912 handler, eloop_data, 913 user_data); 914 return 1; 915 } 916 return 0; 917 } 918 } 919 920 return -1; 921 } 922 923 924 int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, 925 eloop_timeout_handler handler, void *eloop_data, 926 void *user_data) 927 { 928 struct os_reltime now, requested, remaining; 929 struct eloop_timeout *tmp; 930 931 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 932 if (tmp->handler == handler && 933 tmp->eloop_data == eloop_data && 934 tmp->user_data == user_data) { 935 requested.sec = req_secs; 936 requested.usec = req_usecs; 937 os_get_reltime(&now); 938 os_reltime_sub(&tmp->time, &now, &remaining); 939 if (os_reltime_before(&remaining, &requested)) { 940 eloop_cancel_timeout(handler, eloop_data, 941 user_data); 942 eloop_register_timeout(requested.sec, 943 requested.usec, 944 handler, eloop_data, 945 user_data); 946 return 1; 947 } 948 return 0; 949 } 950 } 951 952 return -1; 953 } 954 955 956 #ifndef CONFIG_NATIVE_WINDOWS 957 static void eloop_handle_alarm(int sig) 958 { 959 wpa_printf(MSG_ERROR, "eloop: could not process SIGINT or SIGTERM in " 960 "two seconds. Looks like there\n" 961 "is a bug that ends up in a busy loop that " 962 "prevents clean shutdown.\n" 963 "Killing program forcefully.\n"); 964 exit(1); 965 } 966 #endif /* CONFIG_NATIVE_WINDOWS */ 967 968 969 static void eloop_handle_signal(int sig) 970 { 971 int i; 972 973 #ifndef CONFIG_NATIVE_WINDOWS 974 if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) { 975 /* Use SIGALRM to break out from potential busy loops that 976 * would not allow the program to be killed. */ 977 eloop.pending_terminate = 1; 978 signal(SIGALRM, eloop_handle_alarm); 979 alarm(2); 980 } 981 #endif /* CONFIG_NATIVE_WINDOWS */ 982 983 eloop.signaled++; 984 for (i = 0; i < eloop.signal_count; i++) { 985 if (eloop.signals[i].sig == sig) { 986 eloop.signals[i].signaled++; 987 break; 988 } 989 } 990 } 991 992 993 static void eloop_process_pending_signals(void) 994 { 995 int i; 996 997 if (eloop.signaled == 0) 998 return; 999 eloop.signaled = 0; 1000 1001 if (eloop.pending_terminate) { 1002 #ifndef CONFIG_NATIVE_WINDOWS 1003 alarm(0); 1004 #endif /* CONFIG_NATIVE_WINDOWS */ 1005 eloop.pending_terminate = 0; 1006 } 1007 1008 for (i = 0; i < eloop.signal_count; i++) { 1009 if (eloop.signals[i].signaled) { 1010 eloop.signals[i].signaled = 0; 1011 eloop.signals[i].handler(eloop.signals[i].sig, 1012 eloop.signals[i].user_data); 1013 } 1014 } 1015 } 1016 1017 1018 int eloop_register_signal(int sig, eloop_signal_handler handler, 1019 void *user_data) 1020 { 1021 struct eloop_signal *tmp; 1022 1023 tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1, 1024 sizeof(struct eloop_signal)); 1025 if (tmp == NULL) 1026 return -1; 1027 1028 tmp[eloop.signal_count].sig = sig; 1029 tmp[eloop.signal_count].user_data = user_data; 1030 tmp[eloop.signal_count].handler = handler; 1031 tmp[eloop.signal_count].signaled = 0; 1032 eloop.signal_count++; 1033 eloop.signals = tmp; 1034 signal(sig, eloop_handle_signal); 1035 1036 return 0; 1037 } 1038 1039 1040 int eloop_register_signal_terminate(eloop_signal_handler handler, 1041 void *user_data) 1042 { 1043 int ret = eloop_register_signal(SIGINT, handler, user_data); 1044 if (ret == 0) 1045 ret = eloop_register_signal(SIGTERM, handler, user_data); 1046 return ret; 1047 } 1048 1049 1050 int eloop_register_signal_reconfig(eloop_signal_handler handler, 1051 void *user_data) 1052 { 1053 #ifdef CONFIG_NATIVE_WINDOWS 1054 return 0; 1055 #else /* CONFIG_NATIVE_WINDOWS */ 1056 return eloop_register_signal(SIGHUP, handler, user_data); 1057 #endif /* CONFIG_NATIVE_WINDOWS */ 1058 } 1059 1060 1061 void eloop_run(void) 1062 { 1063 #ifdef CONFIG_ELOOP_POLL 1064 int num_poll_fds; 1065 int timeout_ms = 0; 1066 #endif /* CONFIG_ELOOP_POLL */ 1067 #ifdef CONFIG_ELOOP_SELECT 1068 fd_set *rfds, *wfds, *efds; 1069 struct timeval _tv; 1070 #endif /* CONFIG_ELOOP_SELECT */ 1071 #ifdef CONFIG_ELOOP_EPOLL 1072 int timeout_ms = -1; 1073 #endif /* CONFIG_ELOOP_EPOLL */ 1074 #ifdef CONFIG_ELOOP_KQUEUE 1075 struct timespec ts; 1076 #endif /* CONFIG_ELOOP_KQUEUE */ 1077 int res; 1078 struct os_reltime tv, now; 1079 1080 #ifdef CONFIG_ELOOP_SELECT 1081 rfds = os_malloc(sizeof(*rfds)); 1082 wfds = os_malloc(sizeof(*wfds)); 1083 efds = os_malloc(sizeof(*efds)); 1084 if (rfds == NULL || wfds == NULL || efds == NULL) 1085 goto out; 1086 #endif /* CONFIG_ELOOP_SELECT */ 1087 1088 while (!eloop.terminate && 1089 (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 || 1090 eloop.writers.count > 0 || eloop.exceptions.count > 0)) { 1091 struct eloop_timeout *timeout; 1092 1093 if (eloop.pending_terminate) { 1094 /* 1095 * This may happen in some corner cases where a signal 1096 * is received during a blocking operation. We need to 1097 * process the pending signals and exit if requested to 1098 * avoid hitting the SIGALRM limit if the blocking 1099 * operation took more than two seconds. 1100 */ 1101 eloop_process_pending_signals(); 1102 if (eloop.terminate) 1103 break; 1104 } 1105 1106 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, 1107 list); 1108 if (timeout) { 1109 os_get_reltime(&now); 1110 if (os_reltime_before(&now, &timeout->time)) 1111 os_reltime_sub(&timeout->time, &now, &tv); 1112 else 1113 tv.sec = tv.usec = 0; 1114 #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) 1115 timeout_ms = tv.sec * 1000 + tv.usec / 1000; 1116 #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ 1117 #ifdef CONFIG_ELOOP_SELECT 1118 _tv.tv_sec = tv.sec; 1119 _tv.tv_usec = tv.usec; 1120 #endif /* CONFIG_ELOOP_SELECT */ 1121 #ifdef CONFIG_ELOOP_KQUEUE 1122 ts.tv_sec = tv.sec; 1123 ts.tv_nsec = tv.usec * 1000L; 1124 #endif /* CONFIG_ELOOP_KQUEUE */ 1125 } 1126 1127 #ifdef CONFIG_ELOOP_POLL 1128 num_poll_fds = eloop_sock_table_set_fds( 1129 &eloop.readers, &eloop.writers, &eloop.exceptions, 1130 eloop.pollfds, eloop.pollfds_map, 1131 eloop.max_pollfd_map); 1132 res = poll(eloop.pollfds, num_poll_fds, 1133 timeout ? timeout_ms : -1); 1134 #endif /* CONFIG_ELOOP_POLL */ 1135 #ifdef CONFIG_ELOOP_SELECT 1136 eloop_sock_table_set_fds(&eloop.readers, rfds); 1137 eloop_sock_table_set_fds(&eloop.writers, wfds); 1138 eloop_sock_table_set_fds(&eloop.exceptions, efds); 1139 res = select(eloop.max_sock + 1, rfds, wfds, efds, 1140 timeout ? &_tv : NULL); 1141 #endif /* CONFIG_ELOOP_SELECT */ 1142 #ifdef CONFIG_ELOOP_EPOLL 1143 if (eloop.count == 0) { 1144 res = 0; 1145 } else { 1146 res = epoll_wait(eloop.epollfd, eloop.epoll_events, 1147 eloop.count, timeout_ms); 1148 } 1149 #endif /* CONFIG_ELOOP_EPOLL */ 1150 #ifdef CONFIG_ELOOP_KQUEUE 1151 if (eloop.count == 0) { 1152 res = 0; 1153 } else { 1154 res = kevent(eloop.kqueuefd, NULL, 0, 1155 eloop.kqueue_events, eloop.kqueue_nevents, 1156 timeout ? &ts : NULL); 1157 } 1158 #endif /* CONFIG_ELOOP_KQUEUE */ 1159 if (res < 0 && errno != EINTR && errno != 0) { 1160 wpa_printf(MSG_ERROR, "eloop: %s: %s", 1161 #ifdef CONFIG_ELOOP_POLL 1162 "poll" 1163 #endif /* CONFIG_ELOOP_POLL */ 1164 #ifdef CONFIG_ELOOP_SELECT 1165 "select" 1166 #endif /* CONFIG_ELOOP_SELECT */ 1167 #ifdef CONFIG_ELOOP_EPOLL 1168 "epoll" 1169 #endif /* CONFIG_ELOOP_EPOLL */ 1170 #ifdef CONFIG_ELOOP_KQUEUE 1171 "kqueue" 1172 #endif /* CONFIG_ELOOP_EKQUEUE */ 1173 1174 , strerror(errno)); 1175 goto out; 1176 } 1177 1178 eloop.readers.changed = 0; 1179 eloop.writers.changed = 0; 1180 eloop.exceptions.changed = 0; 1181 1182 eloop_process_pending_signals(); 1183 1184 1185 /* check if some registered timeouts have occurred */ 1186 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, 1187 list); 1188 if (timeout) { 1189 os_get_reltime(&now); 1190 if (!os_reltime_before(&now, &timeout->time)) { 1191 void *eloop_data = timeout->eloop_data; 1192 void *user_data = timeout->user_data; 1193 eloop_timeout_handler handler = 1194 timeout->handler; 1195 eloop_remove_timeout(timeout); 1196 handler(eloop_data, user_data); 1197 } 1198 1199 } 1200 1201 if (res <= 0) 1202 continue; 1203 1204 if (eloop.readers.changed || 1205 eloop.writers.changed || 1206 eloop.exceptions.changed) { 1207 /* 1208 * Sockets may have been closed and reopened with the 1209 * same FD in the signal or timeout handlers, so we 1210 * must skip the previous results and check again 1211 * whether any of the currently registered sockets have 1212 * events. 1213 */ 1214 continue; 1215 } 1216 1217 #ifdef CONFIG_ELOOP_POLL 1218 eloop_sock_table_dispatch(&eloop.readers, &eloop.writers, 1219 &eloop.exceptions, eloop.pollfds_map, 1220 eloop.max_pollfd_map); 1221 #endif /* CONFIG_ELOOP_POLL */ 1222 #ifdef CONFIG_ELOOP_SELECT 1223 eloop_sock_table_dispatch(&eloop.readers, rfds); 1224 eloop_sock_table_dispatch(&eloop.writers, wfds); 1225 eloop_sock_table_dispatch(&eloop.exceptions, efds); 1226 #endif /* CONFIG_ELOOP_SELECT */ 1227 #ifdef CONFIG_ELOOP_EPOLL 1228 eloop_sock_table_dispatch(eloop.epoll_events, res); 1229 #endif /* CONFIG_ELOOP_EPOLL */ 1230 #ifdef CONFIG_ELOOP_KQUEUE 1231 eloop_sock_table_dispatch(eloop.kqueue_events, res); 1232 #endif /* CONFIG_ELOOP_KQUEUE */ 1233 } 1234 1235 eloop.terminate = 0; 1236 out: 1237 #ifdef CONFIG_ELOOP_SELECT 1238 os_free(rfds); 1239 os_free(wfds); 1240 os_free(efds); 1241 #endif /* CONFIG_ELOOP_SELECT */ 1242 return; 1243 } 1244 1245 1246 void eloop_terminate(void) 1247 { 1248 eloop.terminate = 1; 1249 } 1250 1251 1252 void eloop_destroy(void) 1253 { 1254 struct eloop_timeout *timeout, *prev; 1255 struct os_reltime now; 1256 1257 os_get_reltime(&now); 1258 dl_list_for_each_safe(timeout, prev, &eloop.timeout, 1259 struct eloop_timeout, list) { 1260 int sec, usec; 1261 sec = timeout->time.sec - now.sec; 1262 usec = timeout->time.usec - now.usec; 1263 if (timeout->time.usec < now.usec) { 1264 sec--; 1265 usec += 1000000; 1266 } 1267 wpa_printf(MSG_INFO, "ELOOP: remaining timeout: %d.%06d " 1268 "eloop_data=%p user_data=%p handler=%p", 1269 sec, usec, timeout->eloop_data, timeout->user_data, 1270 timeout->handler); 1271 wpa_trace_dump_funcname("eloop unregistered timeout handler", 1272 timeout->handler); 1273 wpa_trace_dump("eloop timeout", timeout); 1274 eloop_remove_timeout(timeout); 1275 } 1276 eloop_sock_table_destroy(&eloop.readers); 1277 eloop_sock_table_destroy(&eloop.writers); 1278 eloop_sock_table_destroy(&eloop.exceptions); 1279 os_free(eloop.signals); 1280 1281 #ifdef CONFIG_ELOOP_POLL 1282 os_free(eloop.pollfds); 1283 os_free(eloop.pollfds_map); 1284 #endif /* CONFIG_ELOOP_POLL */ 1285 #if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE) 1286 os_free(eloop.fd_table); 1287 #endif /* CONFIG_ELOOP_EPOLL || CONFIG_ELOOP_KQUEUE */ 1288 #ifdef CONFIG_ELOOP_EPOLL 1289 os_free(eloop.epoll_events); 1290 close(eloop.epollfd); 1291 #endif /* CONFIG_ELOOP_EPOLL */ 1292 #ifdef CONFIG_ELOOP_KQUEUE 1293 os_free(eloop.kqueue_events); 1294 close(eloop.kqueuefd); 1295 #endif /* CONFIG_ELOOP_KQUEUE */ 1296 } 1297 1298 1299 int eloop_terminated(void) 1300 { 1301 return eloop.terminate || eloop.pending_terminate; 1302 } 1303 1304 1305 void eloop_wait_for_read_sock(int sock) 1306 { 1307 #ifdef CONFIG_ELOOP_POLL 1308 struct pollfd pfd; 1309 1310 if (sock < 0) 1311 return; 1312 1313 os_memset(&pfd, 0, sizeof(pfd)); 1314 pfd.fd = sock; 1315 pfd.events = POLLIN; 1316 1317 poll(&pfd, 1, -1); 1318 #endif /* CONFIG_ELOOP_POLL */ 1319 #if defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL) 1320 /* 1321 * We can use epoll() here. But epoll() requres 4 system calls. 1322 * epoll_create1(), epoll_ctl() for ADD, epoll_wait, and close() for 1323 * epoll fd. So select() is better for performance here. 1324 */ 1325 fd_set rfds; 1326 1327 if (sock < 0) 1328 return; 1329 1330 FD_ZERO(&rfds); 1331 FD_SET(sock, &rfds); 1332 select(sock + 1, &rfds, NULL, NULL, NULL); 1333 #endif /* defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL) */ 1334 #ifdef CONFIG_ELOOP_KQUEUE 1335 int kfd; 1336 struct kevent ke1, ke2; 1337 1338 kfd = kqueue(); 1339 if (kfd == -1) 1340 return; 1341 EV_SET(&ke1, sock, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0); 1342 kevent(kfd, &ke1, 1, &ke2, 1, NULL); 1343 close(kfd); 1344 #endif /* CONFIG_ELOOP_KQUEUE */ 1345 } 1346 1347 #ifdef CONFIG_ELOOP_SELECT 1348 #undef CONFIG_ELOOP_SELECT 1349 #endif /* CONFIG_ELOOP_SELECT */ 1350