1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, Brian Swetland <swetland@frotz.net> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 50e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** Licensed under the Apache License, Version 2.0 (the "License"); 60e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** you may not use this file except in compliance with the License. 70e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 90e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 110e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** Unless required by applicable law or agreed to in writing, software 120e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** distributed under the License is distributed on an "AS IS" BASIS, 130e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#include <sys/ioctl.h> 19408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stddef.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31d3fc15f4841a8cbfd15fa9f051f2712266b5cd78leozwang#include "adb_trace.h" 32414ff7d98ac8d7610a26206335954ad15f43f3acDavid 'Digit' Turner#include "fdevent.h" 33408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#include "transport.h" 34408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#include "sysdeps.h" 35408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 36d3fc15f4841a8cbfd15fa9f051f2712266b5cd78leozwang#define TRACE_TAG TRACE_FDEVENT 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall/* !!! Do not enable DEBUG for the adb that will run as the server: 39408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall** both stdout and stderr are used to communicate between the client 40408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall** and server. Any extra output will cause failures. 41408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall*/ 42408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define DEBUG 0 /* non-0 will break adb server */ 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall// This socket is used when a subproc shell service exists. 45408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall// It wakes up the fdevent_loop() and cause the correct handling 46408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall// of the shell's pseudo-tty master. I.e. force close it. 47408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallint SHELL_EXIT_NOTIFY_FD = -1; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fatal(const char *fn, const char *fmt, ...) 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s:", fn); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vfprintf(stderr, fmt, ap); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project abort(); 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FATAL(x...) fatal(__FUNCTION__, x) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_fde(fdevent *fde, const char *info) 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 64408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_mutex_lock(&D_lock); 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state & FDE_READ ? 'R' : ' ', 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state & FDE_WRITE ? 'W' : ' ', 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state & FDE_ERROR ? 'E' : ' ', 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info); 70408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_mutex_unlock(&D_lock); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define dump_fde(fde, info) do { } while(0) 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_EVENTMASK 0x00ff 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_STATEMASK 0xff00 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_ACTIVE 0x0100 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_PENDING 0x0200 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_CREATED 0x0400 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_enqueue(fdevent *node); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_remove(fdevent *node); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent *fdevent_plist_dequeue(void); 86408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void fdevent_subproc_event_func(int fd, unsigned events, void *userdata); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent list_pending = { 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &list_pending, 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &list_pending, 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent **fd_table = 0; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fd_table_max = 0; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef CRAPTASTIC 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//HAVE_EPOLL 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/epoll.h> 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int epoll_fd = -1; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_init() 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX: what's a good size for the passed in hint? */ 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project epoll_fd = epoll_create(256); 107f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(epoll_fd < 0) { 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_create() failed"); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* mark for close-on-exec */ 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(epoll_fd, F_SETFD, FD_CLOEXEC); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_connect(fdevent *fde) 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct epoll_event ev; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&ev, 0, sizeof(ev)); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.events = 0; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.data.ptr = fde; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 125f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner#if 0 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_ctl() failed\n"); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_disconnect(fdevent *fde) 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct epoll_event ev; 136f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&ev, 0, sizeof(ev)); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.events = 0; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.data.ptr = fde; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* technically we only need to delete if we 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** were actively monitoring events, but let's 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** be aggressive and do it anyway, just in case 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** something's out of sync 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_update(fdevent *fde, unsigned events) 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct epoll_event ev; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int active; 153f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = (fde->state & FDE_EVENTMASK) != 0; 155f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&ev, 0, sizeof(ev)); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.events = 0; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ev.data.ptr = fde; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_READ) ev.events |= EPOLLIN; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_WRITE) ev.events |= EPOLLOUT; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP); 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state = (fde->state & FDE_STATEMASK) | events; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(active) { 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we're already active. if we're changing to *no* 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** events being monitored, we need to delete, otherwise 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** we need to just modify 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev.events) { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) { 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_ctl() failed\n"); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) { 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_ctl() failed\n"); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we're not active. if we're watching events, we need 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** to add, otherwise we can just do nothing 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev.events) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_ctl() failed\n"); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_process() 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct epoll_event events[256]; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *fde; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, n; 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = epoll_wait(epoll_fd, events, 256, -1); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(n < 0) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) return; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("epoll_wait"); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(i = 0; i < n; i++) { 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct epoll_event *ev = events + i; 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde = ev->data.ptr; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev->events & EPOLLIN) { 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events |= FDE_READ; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev->events & EPOLLOUT) { 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events |= FDE_WRITE; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev->events & (EPOLLERR | EPOLLHUP)) { 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events |= FDE_ERROR; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->events) { 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_PENDING) continue; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state |= FDE_PENDING; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_plist_enqueue(fde); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* USE_SELECT */ 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_WINSOCK 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winsock2.h> 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/select.h> 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fd_set read_fds; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fd_set write_fds; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fd_set error_fds; 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int select_n = 0; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_init(void) 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_ZERO(&read_fds); 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_ZERO(&write_fds); 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_ZERO(&error_fds); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_connect(fdevent *fde) 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->fd >= select_n) { 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project select_n = fde->fd + 1; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_disconnect(fdevent *fde) 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, n; 261f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &read_fds); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &write_fds); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &error_fds); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(n = 0, i = 0; i < select_n; i++) { 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd_table[i] != 0) n = i; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project select_n = n + 1; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_update(fdevent *fde, unsigned events) 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_READ) { 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_SET(fde->fd, &read_fds); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &read_fds); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_WRITE) { 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_SET(fde->fd, &write_fds); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &write_fds); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_ERROR) { 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_SET(fde->fd, &error_fds); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FD_CLR(fde->fd, &error_fds); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->state = (fde->state & FDE_STATEMASK) | events; 291408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 292408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 293408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall/* Looks at fd_table[] for bad FDs and sets bit in fds. 294408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall** Returns the number of bad FDs. 295408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall*/ 296408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic int fdevent_fd_check(fd_set *fds) 297408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 298408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int i, n = 0; 299408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent *fde; 300408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 301408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall for(i = 0; i < select_n; i++) { 302408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde = fd_table[i]; 303408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(fde == 0) continue; 304408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(fcntl(i, F_GETFL, NULL) < 0) { 305408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FD_SET(i, fds); 306408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall n++; 307408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // fde->state |= FDE_DONT_CLOSE; 308408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 309408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 310408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 311408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return n; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 314408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !DEBUG 315408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic inline void dump_all_fds(const char *extra_msg) {} 316408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#else 317408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void dump_all_fds(const char *extra_msg) 318408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 319408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallint i; 320408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent *fde; 321408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank 322408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff; 323408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall size_t max_chars = FD_SETSIZE * 6 + 1; 324408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int printed_out; 325408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define SAFE_SPRINTF(...) \ 326408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall do { \ 327408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall printed_out = snprintf(pb, max_chars, __VA_ARGS__); \ 328408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (printed_out <= 0) { \ 329408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("... snprintf failed.\n"); \ 330408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; \ 331408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } \ 332408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (max_chars < (unsigned int)printed_out) { \ 333408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("... snprintf out of space.\n"); \ 334408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; \ 335408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } \ 336408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pb += printed_out; \ 337408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall max_chars -= printed_out; \ 338408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } while(0) 339408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 340408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall for(i = 0; i < select_n; i++) { 341408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde = fd_table[i]; 342408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SAFE_SPRINTF("%d", i); 343408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(fde == 0) { 344408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SAFE_SPRINTF("? "); 345408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall continue; 346408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 347408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(fcntl(i, F_GETFL, NULL) < 0) { 348408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SAFE_SPRINTF("b"); 349408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 350408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SAFE_SPRINTF(" "); 351408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 352408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff); 353408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 354408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif 355408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_process() 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, n; 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *fde; 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned events; 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_set rfd, wfd, efd; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(&rfd, &read_fds, sizeof(fd_set)); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(&wfd, &write_fds, sizeof(fd_set)); 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(&efd, &error_fds, sizeof(fd_set)); 366f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 367408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall dump_all_fds("pre select()"); 368408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 369408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall n = select(select_n, &rfd, &wfd, &efd, NULL); 370408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 371408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0); 372408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 373408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall dump_all_fds("post select()"); 374f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(n < 0) { 376408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall switch(saved_errno) { 377408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall case EINTR: return; 378408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall case EBADF: 379408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Can't trust the FD sets after an error. 380408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FD_ZERO(&wfd); 381408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FD_ZERO(&efd); 382408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FD_ZERO(&rfd); 383408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 384408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall default: 385408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("Unexpected select() error=%d\n", saved_errno); 386408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 387408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 388408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 389408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(n <= 0) { 390408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // We fake a read, as the rest of the code assumes 391408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // that errors will be detected at that point. 392408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall n = fdevent_fd_check(&rfd); 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(i = 0; (i < select_n) && (n > 0); i++) { 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project events = 0; 397408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; } 398408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; } 399408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; } 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events) { 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde = fd_table[i]; 403408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(fde == 0) 404408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("missing fde for fd %d\n", i); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events |= events; 407f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 408408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("got events fde->fd=%d events=%04x, state=%04x\n", 409408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->fd, fde->events, fde->state); 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_PENDING) continue; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state |= FDE_PENDING; 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_plist_enqueue(fde); 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_register(fdevent *fde) 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->fd < 0) { 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FATAL("bogus negative fd (%d)\n", fde->fd); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 424f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->fd >= fd_table_max) { 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int oldmax = fd_table_max; 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->fd > 32000) { 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FATAL("bogus huuuuge fd (%d)\n", fde->fd); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd_table_max == 0) { 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_init(); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_table_max = 256; 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(fd_table_max <= fde->fd) { 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_table_max *= 2; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max); 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd_table == 0) { 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FATAL("could not expand fd_table to %d entries\n", fd_table_max); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_table[fde->fd] = fde; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_unregister(fdevent *fde) 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((fde->fd < 0) || (fde->fd >= fd_table_max)) { 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FATAL("fd out of range (%d)\n", fde->fd); 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd_table[fde->fd] != fde) { 454408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("fd_table out of sync [%d]\n", fde->fd); 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_table[fde->fd] = 0; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(fde->state & FDE_DONT_CLOSE)) { 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_fde(fde, "close"); 461408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(fde->fd); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_enqueue(fdevent *node) 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *list = &list_pending; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->next = list; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->prev = list->prev; 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->prev->next = node; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list->prev = node; 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_remove(fdevent *node) 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->prev->next = node->next; 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->next->prev = node->prev; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->next = 0; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->prev = 0; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent *fdevent_plist_dequeue(void) 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *list = &list_pending; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *node = list->next; 487f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(node == list) return 0; 489f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list->next = node->next; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list->next->prev = list; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->next = 0; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node->prev = 0; 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return node; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 498408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void fdevent_call_fdfunc(fdevent* fde) 499408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 500408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall unsigned events = fde->events; 501408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->events = 0; 502408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(!(fde->state & FDE_PENDING)) return; 503408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->state &= (~FDE_PENDING); 504408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall dump_fde(fde, "callback"); 505408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->func(fde->fd, events, fde->arg); 506408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 507408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 508408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata) 509408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 510408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 511408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc handling on fd=%d ev=%04x\n", fd, ev); 512408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 513408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Hook oneself back into the fde's suitable for select() on read. 514408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if((fd < 0) || (fd >= fd_table_max)) { 515408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("fd %d out of range for fd_table \n", fd); 516408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 517408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent *fde = fd_table[fd]; 518408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent_add(fde, FDE_READ); 519408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 520408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(ev & FDE_READ){ 521408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int subproc_fd; 522408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 523408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(readx(fd, &subproc_fd, sizeof(subproc_fd))) { 524408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("Failed to read the subproc's fd from fd=%d\n", fd); 525408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 526408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) { 527408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc_fd %d out of range 0, fd_table_max=%d\n", 528408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall subproc_fd, fd_table_max); 529408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 530408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 531408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent *subproc_fde = fd_table[subproc_fd]; 532408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(!subproc_fde) { 533408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc_fd %d cleared from fd_table\n", subproc_fd); 534408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 535408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 536408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(subproc_fde->fd != subproc_fd) { 537408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Already reallocated? 538408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd); 539408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 540408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 541408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 542408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall subproc_fde->force_eof = 1; 543408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 544408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int rcount = 0; 545b40367e7bc3f89c3875d50b29fa98c3a541e33a3JP Abgrall ioctl(subproc_fd, FIONREAD, &rcount); 546408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc with fd=%d has rcount=%d err=%d\n", 547408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall subproc_fd, rcount, errno); 548408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 549408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(rcount) { 550408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // If there is data left, it will show up in the select(). 551408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // This works because there is no other thread reading that 552408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // data when in this fd_func(). 553408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 554408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 555408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 556408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("subproc_fde.state=%04x\n", subproc_fde->state); 557408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall subproc_fde->events |= FDE_READ; 558408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(subproc_fde->state & FDE_PENDING) { 559408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return; 560408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 561408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall subproc_fde->state |= FDE_PENDING; 562408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent_call_fdfunc(subproc_fde); 563408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 564408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 565408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfdevent *fdevent_create(int fd, fd_func func, void *arg) 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde == 0) return 0; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(fde, fd, func, arg); 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state |= FDE_CREATED; 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fde; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_destroy(fdevent *fde) 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde == 0) return; 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(fde->state & FDE_CREATED)) { 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FATAL("fde %p not created by fdevent_create()\n", fde); 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(fde); 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallvoid fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(fde, 0, sizeof(fdevent)); 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state = FDE_ACTIVE; 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->fd = fd; 589408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde->force_eof = 0; 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->func = func; 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->arg = arg; 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_WINSOCK 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(fd, F_SETFL, O_NONBLOCK); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_register(fde); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_fde(fde, "connect"); 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_connect(fde); 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state |= FDE_ACTIVE; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_remove(fdevent *fde) 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_PENDING) { 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_plist_remove(fde); 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_ACTIVE) { 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_disconnect(fde); 610408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall dump_fde(fde, "disconnect"); 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_unregister(fde); 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state = 0; 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events = 0; 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_set(fdevent *fde, unsigned events) 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project events &= FDE_EVENTMASK; 622f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((fde->state & FDE_EVENTMASK) == events) return; 624f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_ACTIVE) { 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_update(fde, events); 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_fde(fde, "update"); 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state = (fde->state & FDE_STATEMASK) | events; 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->state & FDE_PENDING) { 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if we're pending, make sure 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** we don't signal an event that 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** is no longer wanted. 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->events &= (~events); 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fde->events == 0) { 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_plist_remove(fde); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde->state &= (~FDE_PENDING); 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_add(fdevent *fde, unsigned events) 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set( 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_del(fdevent *fde, unsigned events) 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set( 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 657408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallvoid fdevent_subproc_setup() 658408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 659408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int s[2]; 660408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 661408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(adb_socketpair(s)) { 662408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("cannot create shell-exit socket-pair\n"); 663408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 664408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SHELL_EXIT_NOTIFY_FD = s[0]; 665408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent *fde; 666408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); 667408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(!fde) 668408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall FATAL("cannot create fdevent for shell-exit handler\n"); 669408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent_add(fde, FDE_READ); 670408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 671408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_loop() 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent *fde; 675408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent_subproc_setup(); 676f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 678408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("--- ---- waiting for events\n"); 679408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_process(); 681f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((fde = fdevent_plist_dequeue())) { 683408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fdevent_call_fdfunc(fde); 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 687