1
/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c
3
** Copyright 2006, Brian Swetland <swetland@frotz.net>
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
9
** http://www.apache.org/licenses/LICENSE-2.0
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.
18
#include <sys/ioctl.h>
32
#include "transport.h"
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.
40
#define DEBUG 0 /* non-0 will break adb server */
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.
45
int SHELL_EXIT_NOTIFY_FD = -1;
47
static void fatal(const char *fn, const char *fmt, ...)
51
fprintf(stderr, "%s:", fn);
52
vfprintf(stderr, fmt, ap);
57
#define FATAL(x...) fatal(__FUNCTION__, x)
62
adb_mutex_lock(&D_lock); \
63
int save_errno = errno; \
64
fprintf(stderr, "%s::%s():", __FILE__, __FUNCTION__); \
66
fprintf(stderr, __VA_ARGS__); \
67
adb_mutex_unlock(&D_lock); \
70
static void dump_fde(fdevent *fde, const char *info)
72
adb_mutex_lock(&D_lock);
73
fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
74
fde->state & FDE_READ ? 'R' : ' ',
75
fde->state & FDE_WRITE ? 'W' : ' ',
76
fde->state & FDE_ERROR ? 'E' : ' ',
78
adb_mutex_unlock(&D_lock);
81
#define D(...) ((void)0)
82
#define dump_fde(fde, info) do { } while(0)
85
#define FDE_EVENTMASK 0x00ff
86
#define FDE_STATEMASK 0xff00
88
#define FDE_ACTIVE 0x0100
89
#define FDE_PENDING 0x0200
90
#define FDE_CREATED 0x0400
92
static void fdevent_plist_enqueue(fdevent *node);
93
static void fdevent_plist_remove(fdevent *node);
94
static fdevent *fdevent_plist_dequeue(void);
95
static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata);
97
static fdevent list_pending = {
98
.next = &list_pending,
99
.prev = &list_pending,
102
static fdevent **fd_table = 0;
103
static int fd_table_max = 0;
108
#include <sys/epoll.h>
110
static int epoll_fd = -1;
112
static void fdevent_init()
114
/* XXX: what's a good size for the passed in hint? */
115
epoll_fd = epoll_create(256);
118
perror("epoll_create() failed");
122
/* mark for close-on-exec */
123
fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
126
static void fdevent_connect(fdevent *fde)
128
struct epoll_event ev;
130
memset(&ev, 0, sizeof(ev));
135
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
136
perror("epoll_ctl() failed\n");
142
static void fdevent_disconnect(fdevent *fde)
144
struct epoll_event ev;
146
memset(&ev, 0, sizeof(ev));
150
/* technically we only need to delete if we
151
** were actively monitoring events, but let's
152
** be aggressive and do it anyway, just in case
153
** something's out of sync
155
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev);
158
static void fdevent_update(fdevent *fde, unsigned events)
160
struct epoll_event ev;
163
active = (fde->state & FDE_EVENTMASK) != 0;
165
memset(&ev, 0, sizeof(ev));
169
if(events & FDE_READ) ev.events |= EPOLLIN;
170
if(events & FDE_WRITE) ev.events |= EPOLLOUT;
171
if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);
173
fde->state = (fde->state & FDE_STATEMASK) | events;
176
/* we're already active. if we're changing to *no*
177
** events being monitored, we need to delete, otherwise
178
** we need to just modify
181
if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
182
perror("epoll_ctl() failed\n");
186
if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
187
perror("epoll_ctl() failed\n");
192
/* we're not active. if we're watching events, we need
193
** to add, otherwise we can just do nothing
196
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
197
perror("epoll_ctl() failed\n");
204
static void fdevent_process()
206
struct epoll_event events[256];
210
n = epoll_wait(epoll_fd, events, 256, -1);
213
if(errno == EINTR) return;
214
perror("epoll_wait");
218
for(i = 0; i < n; i++) {
219
struct epoll_event *ev = events + i;
222
if(ev->events & EPOLLIN) {
223
fde->events |= FDE_READ;
225
if(ev->events & EPOLLOUT) {
226
fde->events |= FDE_WRITE;
228
if(ev->events & (EPOLLERR | EPOLLHUP)) {
229
fde->events |= FDE_ERROR;
232
if(fde->state & FDE_PENDING) continue;
233
fde->state |= FDE_PENDING;
234
fdevent_plist_enqueue(fde);
239
#else /* USE_SELECT */
242
#include <winsock2.h>
244
#include <sys/select.h>
247
static fd_set read_fds;
248
static fd_set write_fds;
249
static fd_set error_fds;
251
static int select_n = 0;
253
static void fdevent_init(void)
260
static void fdevent_connect(fdevent *fde)
262
if(fde->fd >= select_n) {
263
select_n = fde->fd + 1;
267
static void fdevent_disconnect(fdevent *fde)
271
FD_CLR(fde->fd, &read_fds);
272
FD_CLR(fde->fd, &write_fds);
273
FD_CLR(fde->fd, &error_fds);
275
for(n = 0, i = 0; i < select_n; i++) {
276
if(fd_table[i] != 0) n = i;
281
static void fdevent_update(fdevent *fde, unsigned events)
283
if(events & FDE_READ) {
284
FD_SET(fde->fd, &read_fds);
286
FD_CLR(fde->fd, &read_fds);
288
if(events & FDE_WRITE) {
289
FD_SET(fde->fd, &write_fds);
291
FD_CLR(fde->fd, &write_fds);
293
if(events & FDE_ERROR) {
294
FD_SET(fde->fd, &error_fds);
296
FD_CLR(fde->fd, &error_fds);
299
fde->state = (fde->state & FDE_STATEMASK) | events;
302
/* Looks at fd_table[] for bad FDs and sets bit in fds.
303
** Returns the number of bad FDs.
305
static int fdevent_fd_check(fd_set *fds)
310
for(i = 0; i < select_n; i++) {
312
if(fde == 0) continue;
313
if(fcntl(i, F_GETFL, NULL) < 0) {
316
// fde->state |= FDE_DONT_CLOSE;
324
static inline void dump_all_fds(const char *extra_msg) {}
326
static void dump_all_fds(const char *extra_msg)
330
// per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank
331
char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff;
332
size_t max_chars = FD_SETSIZE * 6 + 1;
334
#define SAFE_SPRINTF(...) \
336
printed_out = snprintf(pb, max_chars, __VA_ARGS__); \
337
if (printed_out <= 0) { \
338
D("... snprintf failed.\n"); \
341
if (max_chars < (unsigned int)printed_out) { \
342
D("... snprintf out of space.\n"); \
346
max_chars -= printed_out; \
349
for(i = 0; i < select_n; i++) {
351
SAFE_SPRINTF("%d", i);
356
if(fcntl(i, F_GETFL, NULL) < 0) {
361
D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff);
365
static void fdevent_process()
370
fd_set rfd, wfd, efd;
372
memcpy(&rfd, &read_fds, sizeof(fd_set));
373
memcpy(&wfd, &write_fds, sizeof(fd_set));
374
memcpy(&efd, &error_fds, sizeof(fd_set));
376
dump_all_fds("pre select()");
378
n = select(select_n, &rfd, &wfd, &efd, NULL);
379
int saved_errno = errno;
380
D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
382
dump_all_fds("post select()");
385
switch(saved_errno) {
388
// Can't trust the FD sets after an error.
394
D("Unexpected select() error=%d\n", saved_errno);
399
// We fake a read, as the rest of the code assumes
400
// that errors will be detected at that point.
401
n = fdevent_fd_check(&rfd);
404
for(i = 0; (i < select_n) && (n > 0); i++) {
406
if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; }
407
if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; }
408
if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; }
413
FATAL("missing fde for fd %d\n", i);
415
fde->events |= events;
417
D("got events fde->fd=%d events=%04x, state=%04x\n",
418
fde->fd, fde->events, fde->state);
419
if(fde->state & FDE_PENDING) continue;
420
fde->state |= FDE_PENDING;
421
fdevent_plist_enqueue(fde);
428
static void fdevent_register(fdevent *fde)
431
FATAL("bogus negative fd (%d)\n", fde->fd);
434
if(fde->fd >= fd_table_max) {
435
int oldmax = fd_table_max;
436
if(fde->fd > 32000) {
437
FATAL("bogus huuuuge fd (%d)\n", fde->fd);
439
if(fd_table_max == 0) {
443
while(fd_table_max <= fde->fd) {
446
fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
448
FATAL("could not expand fd_table to %d entries\n", fd_table_max);
450
memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
453
fd_table[fde->fd] = fde;
456
static void fdevent_unregister(fdevent *fde)
458
if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
459
FATAL("fd out of range (%d)\n", fde->fd);
462
if(fd_table[fde->fd] != fde) {
463
FATAL("fd_table out of sync [%d]\n", fde->fd);
466
fd_table[fde->fd] = 0;
468
if(!(fde->state & FDE_DONT_CLOSE)) {
469
dump_fde(fde, "close");
474
static void fdevent_plist_enqueue(fdevent *node)
476
fdevent *list = &list_pending;
479
node->prev = list->prev;
480
node->prev->next = node;
484
static void fdevent_plist_remove(fdevent *node)
486
node->prev->next = node->next;
487
node->next->prev = node->prev;
492
static fdevent *fdevent_plist_dequeue(void)
494
fdevent *list = &list_pending;
495
fdevent *node = list->next;
497
if(node == list) return 0;
499
list->next = node->next;
500
list->next->prev = list;
507
static void fdevent_call_fdfunc(fdevent* fde)
509
unsigned events = fde->events;
511
if(!(fde->state & FDE_PENDING)) return;
512
fde->state &= (~FDE_PENDING);
513
dump_fde(fde, "callback");
514
fde->func(fde->fd, events, fde->arg);
517
static void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata)
520
D("subproc handling on fd=%d ev=%04x\n", fd, ev);
522
// Hook oneself back into the fde's suitable for select() on read.
523
if((fd < 0) || (fd >= fd_table_max)) {
524
FATAL("fd %d out of range for fd_table \n", fd);
526
fdevent *fde = fd_table[fd];
527
fdevent_add(fde, FDE_READ);
532
if(readx(fd, &subproc_fd, sizeof(subproc_fd))) {
533
FATAL("Failed to read the subproc's fd from fd=%d\n", fd);
535
if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
536
D("subproc_fd %d out of range 0, fd_table_max=%d\n",
537
subproc_fd, fd_table_max);
540
fdevent *subproc_fde = fd_table[subproc_fd];
542
D("subproc_fd %d cleared from fd_table\n", subproc_fd);
545
if(subproc_fde->fd != subproc_fd) {
546
// Already reallocated?
547
D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
551
subproc_fde->force_eof = 1;
554
ioctl(subproc_fd, FIONREAD, &rcount);
555
D("subproc with fd=%d has rcount=%d err=%d\n",
556
subproc_fd, rcount, errno);
559
// If there is data left, it will show up in the select().
560
// This works because there is no other thread reading that
561
// data when in this fd_func().
565
D("subproc_fde.state=%04x\n", subproc_fde->state);
566
subproc_fde->events |= FDE_READ;
567
if(subproc_fde->state & FDE_PENDING) {
570
subproc_fde->state |= FDE_PENDING;
571
fdevent_call_fdfunc(subproc_fde);
575
fdevent *fdevent_create(int fd, fd_func func, void *arg)
577
fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
578
if(fde == 0) return 0;
579
fdevent_install(fde, fd, func, arg);
580
fde->state |= FDE_CREATED;
584
void fdevent_destroy(fdevent *fde)
587
if(!(fde->state & FDE_CREATED)) {
588
FATAL("fde %p not created by fdevent_create()\n", fde);
593
void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
595
memset(fde, 0, sizeof(fdevent));
596
fde->state = FDE_ACTIVE;
603
fcntl(fd, F_SETFL, O_NONBLOCK);
605
fdevent_register(fde);
606
dump_fde(fde, "connect");
607
fdevent_connect(fde);
608
fde->state |= FDE_ACTIVE;
611
void fdevent_remove(fdevent *fde)
613
if(fde->state & FDE_PENDING) {
614
fdevent_plist_remove(fde);
617
if(fde->state & FDE_ACTIVE) {
618
fdevent_disconnect(fde);
619
dump_fde(fde, "disconnect");
620
fdevent_unregister(fde);
628
void fdevent_set(fdevent *fde, unsigned events)
630
events &= FDE_EVENTMASK;
632
if((fde->state & FDE_EVENTMASK) == events) return;
634
if(fde->state & FDE_ACTIVE) {
635
fdevent_update(fde, events);
636
dump_fde(fde, "update");
639
fde->state = (fde->state & FDE_STATEMASK) | events;
641
if(fde->state & FDE_PENDING) {
642
/* if we're pending, make sure
643
** we don't signal an event that
644
** is no longer wanted.
646
fde->events &= (~events);
647
if(fde->events == 0) {
648
fdevent_plist_remove(fde);
649
fde->state &= (~FDE_PENDING);
654
void fdevent_add(fdevent *fde, unsigned events)
657
fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
660
void fdevent_del(fdevent *fde, unsigned events)
663
fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
666
void fdevent_subproc_setup()
670
if(adb_socketpair(s)) {
671
FATAL("cannot create shell-exit socket-pair\n");
673
SHELL_EXIT_NOTIFY_FD = s[0];
675
fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL);
677
FATAL("cannot create fdevent for shell-exit handler\n");
678
fdevent_add(fde, FDE_READ);
684
fdevent_subproc_setup();
687
D("--- ---- waiting for events\n");
691
while((fde = fdevent_plist_dequeue())) {
692
fdevent_call_fdfunc(fde);