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