static void fdevent_subproc_event_func(int fd, unsigned ev, void* /* userdata */) { ADB_LOGD(ADB_FDEV, "subproc handling on fd=%d ev=%04x", fd, ev); // Hook oneself back into the fde's suitable for select() on read. if ((fd < 0) || (fd >= fd_table_max)) { FATAL("fd %d out of range for fd_table", fd); } fdevent *fde = fd_table[fd]; fdevent_add(fde, FDE_READ); if (ev & FDE_READ) { int subproc_fd; if (!ReadFdExactly(fd, &subproc_fd, sizeof(subproc_fd))) { FATAL("Failed to read the subproc's fd from fd=%d", fd); } if ((subproc_fd < 0) || (subproc_fd >= fd_table_max)) { ADB_LOGD(ADB_FDEV, "subproc_fd %d out of range 0, fd_table_max=%d", subproc_fd, fd_table_max); return; } fdevent *subproc_fde = fd_table[subproc_fd]; if (!subproc_fde) { ADB_LOGD(ADB_FDEV, "subproc_fd %d cleared from fd_table", subproc_fd); return; } if (subproc_fde->fd != subproc_fd) { // Already reallocated? ADB_LOGD(ADB_FDEV, "subproc_fd %d != fd_table[].fd %d", subproc_fd, subproc_fde->fd); return; } subproc_fde->force_eof = 1; int rcount = 0; ioctl(subproc_fd, FIONREAD, &rcount); ADB_LOGD(ADB_FDEV, "subproc with fd=%d has rcount=%d err=%d", subproc_fd, rcount, errno); if (rcount) { // If there is data left, it will show up in the select(). // This works because there is no other thread reading that // data when in this fd_func(). return; } ADB_LOGD(ADB_FDEV, "subproc_fde.state=%04x", subproc_fde->state); subproc_fde->events |= FDE_READ; if (subproc_fde->state & FDE_PENDING) { return; } subproc_fde->state |= FDE_PENDING; fdevent_call_fdfunc(subproc_fde); } }
void fdevent_loop() { fdevent *fde; fdevent_subproc_setup(); for(;;) { D("--- ---- waiting for events\n"); fdevent_process(); while((fde = fdevent_plist_dequeue())) { fdevent_call_fdfunc(fde); } } }
static void fdevent_subproc_event_func(int fd, unsigned ev, void* /* userdata */) { D("subproc handling on fd = %d, ev = %x", fd, ev); CHECK_GE(fd, 0); if (ev & FDE_READ) { int subproc_fd; if(!ReadFdExactly(fd, &subproc_fd, sizeof(subproc_fd))) { LOG(FATAL) << "Failed to read the subproc's fd from " << fd; } auto it = g_poll_node_map.find(subproc_fd); if (it == g_poll_node_map.end()) { D("subproc_fd %d cleared from fd_table", subproc_fd); return; } fdevent* subproc_fde = it->second.fde; if(subproc_fde->fd != subproc_fd) { // Already reallocated? D("subproc_fd(%d) != subproc_fde->fd(%d)", subproc_fd, subproc_fde->fd); return; } subproc_fde->force_eof = 1; int rcount = 0; ioctl(subproc_fd, FIONREAD, &rcount); D("subproc with fd %d has rcount=%d, err=%d", subproc_fd, rcount, errno); if (rcount != 0) { // If there is data left, it will show up in the select(). // This works because there is no other thread reading that // data when in this fd_func(). return; } D("subproc_fde %s", dump_fde(subproc_fde).c_str()); subproc_fde->events |= FDE_READ; if(subproc_fde->state & FDE_PENDING) { return; } subproc_fde->state |= FDE_PENDING; fdevent_call_fdfunc(subproc_fde); } }
void fdevent_loop() { #if !ADB_HOST fdevent_subproc_setup(); #endif // !ADB_HOST while (true) { D("--- --- waiting for events"); fdevent_process(); while (!g_pending_list.empty()) { fdevent* fde = g_pending_list.front(); g_pending_list.pop_front(); fdevent_call_fdfunc(fde); } } }
void fdevent_loop() { printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__); fdevent *fde; fdevent_subproc_setup(); for(;;) { D("--- ---- waiting for events\n"); printf("function = %s, file = %s, line = %u, before fdevent_process \n", __FUNCTION__, __FILE__, __LINE__); fdevent_process(); printf("function = %s, file = %s, line = %u, after fdevent_process \n", __FUNCTION__, __FILE__, __LINE__); while((fde = fdevent_plist_dequeue())) { fdevent_call_fdfunc(fde); } } }