1/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c 2** 3** Copyright 2006, Brian Swetland <swetland@frotz.net> 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#define TRACE_TAG TRACE_FDEVENT 19 20#include "sysdeps.h" 21#include "fdevent.h" 22 23#include <errno.h> 24#include <fcntl.h> 25#include <stdarg.h> 26#include <stddef.h> 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <sys/ioctl.h> 31#include <unistd.h> 32 33#include "adb_io.h" 34#include "adb_trace.h" 35 36/* !!! Do not enable DEBUG for the adb that will run as the server: 37** both stdout and stderr are used to communicate between the client 38** and server. Any extra output will cause failures. 39*/ 40#define DEBUG 0 /* non-0 will break adb server */ 41 42// This socket is used when a subproc shell service exists. 43// It wakes up the fdevent_loop() and cause the correct handling 44// of the shell's pseudo-tty master. I.e. force close it. 45int SHELL_EXIT_NOTIFY_FD = -1; 46 47static void fatal(const char *fn, const char *fmt, ...) 48{ 49 va_list ap; 50 va_start(ap, fmt); 51 fprintf(stderr, "%s:", fn); 52 vfprintf(stderr, fmt, ap); 53 va_end(ap); 54 abort(); 55} 56 57#define FATAL(x...) fatal(__FUNCTION__, x) 58 59#if DEBUG 60static void dump_fde(fdevent *fde, const char *info) 61{ 62 adb_mutex_lock(&D_lock); 63 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, 64 fde->state & FDE_READ ? 'R' : ' ', 65 fde->state & FDE_WRITE ? 'W' : ' ', 66 fde->state & FDE_ERROR ? 'E' : ' ', 67 info); 68 adb_mutex_unlock(&D_lock); 69} 70#else 71#define dump_fde(fde, info) do { } while(0) 72#endif 73 74#define FDE_EVENTMASK 0x00ff 75#define FDE_STATEMASK 0xff00 76 77#define FDE_ACTIVE 0x0100 78#define FDE_PENDING 0x0200 79#define FDE_CREATED 0x0400 80 81static void fdevent_plist_enqueue(fdevent *node); 82static void fdevent_plist_remove(fdevent *node); 83static fdevent *fdevent_plist_dequeue(void); 84static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata); 85 86static fdevent list_pending = { 87 .next = &list_pending, 88 .prev = &list_pending, 89 .fd = -1, 90 .force_eof = 0, 91 .state = 0, 92 .events = 0, 93 .func = nullptr, 94 .arg = nullptr, 95}; 96 97static fdevent **fd_table = 0; 98static int fd_table_max = 0; 99 100#ifdef CRAPTASTIC 101//HAVE_EPOLL 102 103#include <sys/epoll.h> 104 105static int epoll_fd = -1; 106 107static void fdevent_init() 108{ 109 /* XXX: what's a good size for the passed in hint? */ 110 epoll_fd = epoll_create(256); 111 112 if(epoll_fd < 0) { 113 perror("epoll_create() failed"); 114 exit(1); 115 } 116 117 /* mark for close-on-exec */ 118 fcntl(epoll_fd, F_SETFD, FD_CLOEXEC); 119} 120 121static void fdevent_connect(fdevent *fde) 122{ 123 struct epoll_event ev; 124 125 memset(&ev, 0, sizeof(ev)); 126 ev.events = 0; 127 ev.data.ptr = fde; 128 129#if 0 130 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 131 perror("epoll_ctl() failed\n"); 132 exit(1); 133 } 134#endif 135} 136 137static void fdevent_disconnect(fdevent *fde) 138{ 139 struct epoll_event ev; 140 141 memset(&ev, 0, sizeof(ev)); 142 ev.events = 0; 143 ev.data.ptr = fde; 144 145 /* technically we only need to delete if we 146 ** were actively monitoring events, but let's 147 ** be aggressive and do it anyway, just in case 148 ** something's out of sync 149 */ 150 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev); 151} 152 153static void fdevent_update(fdevent *fde, unsigned events) 154{ 155 struct epoll_event ev; 156 int active; 157 158 active = (fde->state & FDE_EVENTMASK) != 0; 159 160 memset(&ev, 0, sizeof(ev)); 161 ev.events = 0; 162 ev.data.ptr = fde; 163 164 if(events & FDE_READ) ev.events |= EPOLLIN; 165 if(events & FDE_WRITE) ev.events |= EPOLLOUT; 166 if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP); 167 168 fde->state = (fde->state & FDE_STATEMASK) | events; 169 170 if(active) { 171 /* we're already active. if we're changing to *no* 172 ** events being monitored, we need to delete, otherwise 173 ** we need to just modify 174 */ 175 if(ev.events) { 176 if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) { 177 perror("epoll_ctl() failed\n"); 178 exit(1); 179 } 180 } else { 181 if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) { 182 perror("epoll_ctl() failed\n"); 183 exit(1); 184 } 185 } 186 } else { 187 /* we're not active. if we're watching events, we need 188 ** to add, otherwise we can just do nothing 189 */ 190 if(ev.events) { 191 if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 192 perror("epoll_ctl() failed\n"); 193 exit(1); 194 } 195 } 196 } 197} 198 199static void fdevent_process() 200{ 201 struct epoll_event events[256]; 202 fdevent *fde; 203 int i, n; 204 205 n = epoll_wait(epoll_fd, events, 256, -1); 206 207 if(n < 0) { 208 if(errno == EINTR) return; 209 perror("epoll_wait"); 210 exit(1); 211 } 212 213 for(i = 0; i < n; i++) { 214 struct epoll_event *ev = events + i; 215 fde = ev->data.ptr; 216 217 if(ev->events & EPOLLIN) { 218 fde->events |= FDE_READ; 219 } 220 if(ev->events & EPOLLOUT) { 221 fde->events |= FDE_WRITE; 222 } 223 if(ev->events & (EPOLLERR | EPOLLHUP)) { 224 fde->events |= FDE_ERROR; 225 } 226 if(fde->events) { 227 if(fde->state & FDE_PENDING) continue; 228 fde->state |= FDE_PENDING; 229 fdevent_plist_enqueue(fde); 230 } 231 } 232} 233 234#else /* USE_SELECT */ 235 236#ifdef HAVE_WINSOCK 237#include <winsock2.h> 238#else 239#include <sys/select.h> 240#endif 241 242static fd_set read_fds; 243static fd_set write_fds; 244static fd_set error_fds; 245 246static int select_n = 0; 247 248static void fdevent_init(void) 249{ 250 FD_ZERO(&read_fds); 251 FD_ZERO(&write_fds); 252 FD_ZERO(&error_fds); 253} 254 255static void fdevent_connect(fdevent *fde) 256{ 257 if(fde->fd >= select_n) { 258 select_n = fde->fd + 1; 259 } 260} 261 262static void fdevent_disconnect(fdevent *fde) 263{ 264 int i, n; 265 266 FD_CLR(fde->fd, &read_fds); 267 FD_CLR(fde->fd, &write_fds); 268 FD_CLR(fde->fd, &error_fds); 269 270 for(n = 0, i = 0; i < select_n; i++) { 271 if(fd_table[i] != 0) n = i; 272 } 273 select_n = n + 1; 274} 275 276static void fdevent_update(fdevent *fde, unsigned events) 277{ 278 if(events & FDE_READ) { 279 FD_SET(fde->fd, &read_fds); 280 } else { 281 FD_CLR(fde->fd, &read_fds); 282 } 283 if(events & FDE_WRITE) { 284 FD_SET(fde->fd, &write_fds); 285 } else { 286 FD_CLR(fde->fd, &write_fds); 287 } 288 if(events & FDE_ERROR) { 289 FD_SET(fde->fd, &error_fds); 290 } else { 291 FD_CLR(fde->fd, &error_fds); 292 } 293 294 fde->state = (fde->state & FDE_STATEMASK) | events; 295} 296 297/* Looks at fd_table[] for bad FDs and sets bit in fds. 298** Returns the number of bad FDs. 299*/ 300static int fdevent_fd_check(fd_set *fds) 301{ 302 int i, n = 0; 303 fdevent *fde; 304 305 for(i = 0; i < select_n; i++) { 306 fde = fd_table[i]; 307 if(fde == 0) continue; 308 if(fcntl(i, F_GETFL, NULL) < 0) { 309 FD_SET(i, fds); 310 n++; 311 // fde->state |= FDE_DONT_CLOSE; 312 313 } 314 } 315 return n; 316} 317 318#if !DEBUG 319static inline void dump_all_fds(const char* /* extra_msg */) {} 320#else 321static void dump_all_fds(const char *extra_msg) 322{ 323int i; 324 fdevent *fde; 325 // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank 326 char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff; 327 size_t max_chars = FD_SETSIZE * 6 + 1; 328 int printed_out; 329#define SAFE_SPRINTF(...) \ 330 do { \ 331 printed_out = snprintf(pb, max_chars, __VA_ARGS__); \ 332 if (printed_out <= 0) { \ 333 D("... snprintf failed.\n"); \ 334 return; \ 335 } \ 336 if (max_chars < (unsigned int)printed_out) { \ 337 D("... snprintf out of space.\n"); \ 338 return; \ 339 } \ 340 pb += printed_out; \ 341 max_chars -= printed_out; \ 342 } while(0) 343 344 for(i = 0; i < select_n; i++) { 345 fde = fd_table[i]; 346 SAFE_SPRINTF("%d", i); 347 if(fde == 0) { 348 SAFE_SPRINTF("? "); 349 continue; 350 } 351 if(fcntl(i, F_GETFL, NULL) < 0) { 352 SAFE_SPRINTF("b"); 353 } 354 SAFE_SPRINTF(" "); 355 } 356 D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff); 357} 358#endif 359 360static void fdevent_process() 361{ 362 int i, n; 363 fdevent *fde; 364 unsigned events; 365 fd_set rfd, wfd, efd; 366 367 memcpy(&rfd, &read_fds, sizeof(fd_set)); 368 memcpy(&wfd, &write_fds, sizeof(fd_set)); 369 memcpy(&efd, &error_fds, sizeof(fd_set)); 370 371 dump_all_fds("pre select()"); 372 373 n = select(select_n, &rfd, &wfd, &efd, NULL); 374 int saved_errno = errno; 375 D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0); 376 377 dump_all_fds("post select()"); 378 379 if(n < 0) { 380 switch(saved_errno) { 381 case EINTR: return; 382 case EBADF: 383 // Can't trust the FD sets after an error. 384 FD_ZERO(&wfd); 385 FD_ZERO(&efd); 386 FD_ZERO(&rfd); 387 break; 388 default: 389 D("Unexpected select() error=%d\n", saved_errno); 390 return; 391 } 392 } 393 if(n <= 0) { 394 // We fake a read, as the rest of the code assumes 395 // that errors will be detected at that point. 396 n = fdevent_fd_check(&rfd); 397 } 398 399 for(i = 0; (i < select_n) && (n > 0); i++) { 400 events = 0; 401 if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; } 402 if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; } 403 if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; } 404 405 if(events) { 406 fde = fd_table[i]; 407 if(fde == 0) 408 FATAL("missing fde for fd %d\n", i); 409 410 fde->events |= events; 411 412 D("got events fde->fd=%d events=%04x, state=%04x\n", 413 fde->fd, fde->events, fde->state); 414 if(fde->state & FDE_PENDING) continue; 415 fde->state |= FDE_PENDING; 416 fdevent_plist_enqueue(fde); 417 } 418 } 419} 420 421#endif 422 423static void fdevent_register(fdevent *fde) 424{ 425 if(fde->fd < 0) { 426 FATAL("bogus negative fd (%d)\n", fde->fd); 427 } 428 429 if(fde->fd >= fd_table_max) { 430 int oldmax = fd_table_max; 431 if(fde->fd > 32000) { 432 FATAL("bogus huuuuge fd (%d)\n", fde->fd); 433 } 434 if(fd_table_max == 0) { 435 fdevent_init(); 436 fd_table_max = 256; 437 } 438 while(fd_table_max <= fde->fd) { 439 fd_table_max *= 2; 440 } 441 fd_table = reinterpret_cast<fdevent**>( 442 realloc(fd_table, sizeof(fdevent*) * fd_table_max)); 443 if(fd_table == 0) { 444 FATAL("could not expand fd_table to %d entries\n", fd_table_max); 445 } 446 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); 447 } 448 449 fd_table[fde->fd] = fde; 450} 451 452static void fdevent_unregister(fdevent *fde) 453{ 454 if((fde->fd < 0) || (fde->fd >= fd_table_max)) { 455 FATAL("fd out of range (%d)\n", fde->fd); 456 } 457 458 if(fd_table[fde->fd] != fde) { 459 FATAL("fd_table out of sync [%d]\n", fde->fd); 460 } 461 462 fd_table[fde->fd] = 0; 463 464 if(!(fde->state & FDE_DONT_CLOSE)) { 465 dump_fde(fde, "close"); 466 adb_close(fde->fd); 467 } 468} 469 470static void fdevent_plist_enqueue(fdevent *node) 471{ 472 fdevent *list = &list_pending; 473 474 node->next = list; 475 node->prev = list->prev; 476 node->prev->next = node; 477 list->prev = node; 478} 479 480static void fdevent_plist_remove(fdevent *node) 481{ 482 node->prev->next = node->next; 483 node->next->prev = node->prev; 484 node->next = 0; 485 node->prev = 0; 486} 487 488static fdevent *fdevent_plist_dequeue(void) 489{ 490 fdevent *list = &list_pending; 491 fdevent *node = list->next; 492 493 if(node == list) return 0; 494 495 list->next = node->next; 496 list->next->prev = list; 497 node->next = 0; 498 node->prev = 0; 499 500 return node; 501} 502 503static void fdevent_call_fdfunc(fdevent* fde) 504{ 505 unsigned events = fde->events; 506 fde->events = 0; 507 if(!(fde->state & FDE_PENDING)) return; 508 fde->state &= (~FDE_PENDING); 509 dump_fde(fde, "callback"); 510 fde->func(fde->fd, events, fde->arg); 511} 512 513static void fdevent_subproc_event_func(int fd, unsigned ev, 514 void* /* userdata */) 515{ 516 517 D("subproc handling on fd=%d ev=%04x\n", fd, ev); 518 519 // Hook oneself back into the fde's suitable for select() on read. 520 if((fd < 0) || (fd >= fd_table_max)) { 521 FATAL("fd %d out of range for fd_table \n", fd); 522 } 523 fdevent *fde = fd_table[fd]; 524 fdevent_add(fde, FDE_READ); 525 526 if(ev & FDE_READ){ 527 int subproc_fd; 528 529 if(!ReadFdExactly(fd, &subproc_fd, sizeof(subproc_fd))) { 530 FATAL("Failed to read the subproc's fd from fd=%d\n", fd); 531 } 532 if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) { 533 D("subproc_fd %d out of range 0, fd_table_max=%d\n", 534 subproc_fd, fd_table_max); 535 return; 536 } 537 fdevent *subproc_fde = fd_table[subproc_fd]; 538 if(!subproc_fde) { 539 D("subproc_fd %d cleared from fd_table\n", subproc_fd); 540 return; 541 } 542 if(subproc_fde->fd != subproc_fd) { 543 // Already reallocated? 544 D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd); 545 return; 546 } 547 548 subproc_fde->force_eof = 1; 549 550 int rcount = 0; 551 ioctl(subproc_fd, FIONREAD, &rcount); 552 D("subproc with fd=%d has rcount=%d err=%d\n", 553 subproc_fd, rcount, errno); 554 555 if(rcount) { 556 // If there is data left, it will show up in the select(). 557 // This works because there is no other thread reading that 558 // data when in this fd_func(). 559 return; 560 } 561 562 D("subproc_fde.state=%04x\n", subproc_fde->state); 563 subproc_fde->events |= FDE_READ; 564 if(subproc_fde->state & FDE_PENDING) { 565 return; 566 } 567 subproc_fde->state |= FDE_PENDING; 568 fdevent_call_fdfunc(subproc_fde); 569 } 570} 571 572fdevent *fdevent_create(int fd, fd_func func, void *arg) 573{ 574 fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); 575 if(fde == 0) return 0; 576 fdevent_install(fde, fd, func, arg); 577 fde->state |= FDE_CREATED; 578 return fde; 579} 580 581void fdevent_destroy(fdevent *fde) 582{ 583 if(fde == 0) return; 584 if(!(fde->state & FDE_CREATED)) { 585 FATAL("fde %p not created by fdevent_create()\n", fde); 586 } 587 fdevent_remove(fde); 588 free(fde); 589} 590 591void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 592{ 593 memset(fde, 0, sizeof(fdevent)); 594 fde->state = FDE_ACTIVE; 595 fde->fd = fd; 596 fde->force_eof = 0; 597 fde->func = func; 598 fde->arg = arg; 599 600#ifndef HAVE_WINSOCK 601 fcntl(fd, F_SETFL, O_NONBLOCK); 602#endif 603 fdevent_register(fde); 604 dump_fde(fde, "connect"); 605 fdevent_connect(fde); 606 fde->state |= FDE_ACTIVE; 607} 608 609void fdevent_remove(fdevent *fde) 610{ 611 if(fde->state & FDE_PENDING) { 612 fdevent_plist_remove(fde); 613 } 614 615 if(fde->state & FDE_ACTIVE) { 616 fdevent_disconnect(fde); 617 dump_fde(fde, "disconnect"); 618 fdevent_unregister(fde); 619 } 620 621 fde->state = 0; 622 fde->events = 0; 623} 624 625 626void fdevent_set(fdevent *fde, unsigned events) 627{ 628 events &= FDE_EVENTMASK; 629 630 if((fde->state & FDE_EVENTMASK) == events) return; 631 632 if(fde->state & FDE_ACTIVE) { 633 fdevent_update(fde, events); 634 dump_fde(fde, "update"); 635 } 636 637 fde->state = (fde->state & FDE_STATEMASK) | events; 638 639 if(fde->state & FDE_PENDING) { 640 /* if we're pending, make sure 641 ** we don't signal an event that 642 ** is no longer wanted. 643 */ 644 fde->events &= (~events); 645 if(fde->events == 0) { 646 fdevent_plist_remove(fde); 647 fde->state &= (~FDE_PENDING); 648 } 649 } 650} 651 652void fdevent_add(fdevent *fde, unsigned events) 653{ 654 fdevent_set( 655 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); 656} 657 658void fdevent_del(fdevent *fde, unsigned events) 659{ 660 fdevent_set( 661 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); 662} 663 664void fdevent_subproc_setup() 665{ 666 int s[2]; 667 668 if(adb_socketpair(s)) { 669 FATAL("cannot create shell-exit socket-pair\n"); 670 } 671 D("socketpair: (%d,%d)", s[0], s[1]); 672 673 SHELL_EXIT_NOTIFY_FD = s[0]; 674 fdevent *fde; 675 fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); 676 if(!fde) 677 FATAL("cannot create fdevent for shell-exit handler\n"); 678 fdevent_add(fde, FDE_READ); 679} 680 681void fdevent_loop() 682{ 683 fdevent *fde; 684 fdevent_subproc_setup(); 685 686 for(;;) { 687 D("--- ---- waiting for events\n"); 688 689 fdevent_process(); 690 691 while((fde = fdevent_plist_dequeue())) { 692 fdevent_call_fdfunc(fde); 693 } 694 } 695} 696