InstallStatus install_listener(const std::string& local_name, const char* connect_to, atransport* transport, int no_rebind, int* resolved_tcp_port, std::string* error) { for (auto& l : listener_list) { if (local_name == l->local_name) { // Can't repurpose a smartsocket. if(l->connect_to[0] == '*') { *error = "cannot repurpose smartsocket"; return INSTALL_STATUS_INTERNAL_ERROR; } // Can't repurpose a listener if 'no_rebind' is true. if (no_rebind) { *error = "cannot rebind"; return INSTALL_STATUS_CANNOT_REBIND; } l->connect_to = connect_to; if (l->transport != transport) { l->transport->RemoveDisconnect(&l->disconnect); l->transport = transport; l->transport->AddDisconnect(&l->disconnect); } return INSTALL_STATUS_OK; } } std::unique_ptr<alistener> listener(new alistener(local_name, connect_to)); listener->fd = local_name_to_fd(listener.get(), resolved_tcp_port, error); if (listener->fd < 0) { return INSTALL_STATUS_CANNOT_BIND; } close_on_exec(listener->fd); if (listener->connect_to == "*smartsocket*") { fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get()); } else { fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get()); } fdevent_set(&listener->fde, FDE_READ); listener->transport = transport; if (transport) { listener->disconnect.opaque = listener.get(); listener->disconnect.func = listener_disconnect; transport->AddDisconnect(&listener->disconnect); } listener_list.push_back(std::move(listener)); return INSTALL_STATUS_OK; }
fdevent *fdevent_create(int fd, fd_func func, void *arg) { fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); if(fde == 0) return 0; fdevent_install(fde, fd, func, arg); fde->state |= FDE_CREATED; return fde; }
static void InvalidFdThreadFunc(void*) { const int INVALID_READ_FD = std::numeric_limits<int>::max() - 1; size_t happened_event_count = 0; InvalidFdArg read_arg; read_arg.expected_events = FDE_READ | FDE_ERROR; read_arg.happened_event_count = &happened_event_count; fdevent_install(&read_arg.fde, INVALID_READ_FD, InvalidFdEventCallback, &read_arg); fdevent_add(&read_arg.fde, FDE_READ); const int INVALID_WRITE_FD = std::numeric_limits<int>::max(); InvalidFdArg write_arg; write_arg.expected_events = FDE_READ | FDE_ERROR; write_arg.happened_event_count = &happened_event_count; fdevent_install(&write_arg.fde, INVALID_WRITE_FD, InvalidFdEventCallback, &write_arg); fdevent_add(&write_arg.fde, FDE_WRITE); fdevent_loop(); }
fdevent *fdevent_create(int fd, fd_func func, void *arg) { printf("function = %s, file = %s, line = %u, fd = %d \n", __FUNCTION__, __FILE__, __LINE__, fd); fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); if(fde == 0) return 0; printf("function = %s, file = %s, line = %u, fdevent_create, fd = %d, func = %p \n", __FUNCTION__, __FILE__, __LINE__, fd, func); fdevent_install(fde, fd, func, arg); fde->state |= FDE_CREATED; return fde; }
asocket *create_local_socket(int fd) { asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); if (s == NULL) fatal("cannot allocate socket"); s->fd = fd; s->enqueue = local_socket_enqueue; s->ready = local_socket_ready; s->shutdown = NULL; s->close = local_socket_close; install_local_socket(s); fdevent_install(&s->fde, fd, local_socket_event_func, s); D("LS(%d): created (fd=%d)\n", s->id, s->fd); return s; }
asocket *create_local_socket(int fd) { asocket *s = (asocket*)calloc(1, sizeof(asocket)); if (s == NULL) fatal("cannot allocate socket"); s->fd = fd; s->enqueue = local_socket_enqueue; s->ready = local_socket_ready; s->close = local_socket_close; install_local_socket(s); fdevent_install(&s->fde, fd, local_socket_event_func, s); /* fdevent_add(&s->fde, FDE_ERROR); */ //fprintf(stderr, "Created local socket in create_local_socket \n"); D("LS(%d): created (fd=%d)\n", s->id, s->fd); return s; }
void init_transport_registration() { int s[2]; if(adb_socketpair(s)){ fatal_errno("cannot open transport registration socketpair"); } transport_registration_send = s[0]; transport_registration_recv = s[1]; fdevent_install(&transport_registration_fde, transport_registration_recv, transport_registration_func, NULL); fdevent_set(&transport_registration_fde, FDE_READ); }
void init_transport_registration(void) { int s[2]; if (adb_socketpair(s)) { fatal_errno("cannot open transport registration socketpair"); } ADB_LOGD(ADB_TSPT, "socketpair: (%d,%d)", s[0], s[1]); transport_registration_send = s[0]; transport_registration_recv = s[1]; fdevent_install(&transport_registration_fde, transport_registration_recv, transport_registration_func, 0); fdevent_set(&transport_registration_fde, FDE_READ); }
static int install_listener(const char *local_name, const char *connect_to, atransport* transport) { alistener *l; //printf("install_listener('%s','%s')\n", local_name, connect_to); for(l = listener_list.next; l != &listener_list; l = l->next){ if(strcmp(local_name, l->local_name) == 0) { char *cto; /* can't repurpose a smartsocket */ if(l->connect_to[0] == '*') { return -1; } cto = strdup(connect_to); if(cto == 0) { return -1; } //printf("rebinding '%s' to '%s'\n", local_name, connect_to); free((void*) l->connect_to); l->connect_to = cto; if (l->transport != transport) { remove_transport_disconnect(l->transport, &l->disconnect); l->transport = transport; add_transport_disconnect(l->transport, &l->disconnect); } return 0; } } if((l = calloc(1, sizeof(alistener))) == 0) goto nomem; if((l->local_name = strdup(local_name)) == 0) goto nomem; if((l->connect_to = strdup(connect_to)) == 0) goto nomem; l->fd = local_name_to_fd(local_name); if(l->fd < 0) { free((void*) l->local_name); free((void*) l->connect_to); free(l); printf("cannot bind '%s'\n", local_name); return -2; } close_on_exec(l->fd); if(!strcmp(l->connect_to, "*smartsocket*")) { fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); } else { fdevent_install(&l->fde, l->fd, listener_event_func, l); } fdevent_set(&l->fde, FDE_READ); l->next = &listener_list; l->prev = listener_list.prev; l->next->prev = l; l->prev->next = l; l->transport = transport; if (transport) { l->disconnect.opaque = l; l->disconnect.func = listener_disconnect; add_transport_disconnect(transport, &l->disconnect); } return 0; nomem: fatal("cannot allocate listener"); return 0; }
static void transport_registration_func(int _fd, unsigned ev, void *data) { tmsg * m = addTMessage(); int s[2]; atransport *t; if(!(ev & FDE_READ)) { return; } if(transport_read_action(_fd, m)) { fatal_errno("cannot read transport registration socket"); } t = m->transport; if(m->action == 0){ D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket); /* IMPORTANT: the remove closes one half of the ** socket pair. The close closes the other half. */ fdevent_remove(&(t->transport_fde)); adb_close(t->fd); adb_mutex_lock(&transport_lock); t->next->prev = t->prev; t->prev->next = t->next; adb_mutex_unlock(&transport_lock); run_transport_disconnects(t); if (t->product) free(t->product); if (t->serial) free(t->serial); if (t->model) free(t->model); if (t->device) free(t->device); if (t->devpath) free(t->devpath); memset(t,0xee,sizeof(atransport)); free(t); update_transports(); return; } /* don't create transport threads for inaccessible devices */ if (t->connection_state != CS_NOPERM) { // adb_thread_t * output_thread_ptr = (adb_thread_t*)malloc(sizeof(adb_thread_t)); // adb_thread_t * input_thread_ptr = (adb_thread_t*)malloc(sizeof(adb_thread_t)); /* initial references are the two threads */ t->ref_count = 2; if(adb_socketpair(s)) { fatal_errno("cannot open transport socketpair"); } D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); t->transport_socket = s[0]; t->fd = s[1]; fdevent_install(&(t->transport_fde), t->transport_socket, transport_socket_events, t); fdevent_set(&(t->transport_fde), FDE_READ); struct msg { atransport * t; }; struct msg m = { t }; send_js_msg("spawn-io-threads", &m); /*char i_tag[1024]; char o_tag[1024]; sprintf(i_tag, "I: %s_%d", t->serial, get_guid()); sprintf(o_tag, "O: %s_%d", t->serial, get_guid());*/ //dump_thread_tag(); /*if(adb_thread_create(input_thread_ptr, input_thread, t, i_tag)){ fatal_errno("cannot create input thread"); } if(adb_thread_create(output_thread_ptr, output_thread, t, o_tag)){ fatal_errno("cannot create output thread"); }*/ } /* put us on the master device list */ adb_mutex_lock(&transport_lock); t->next = &transport_list; t->prev = transport_list.prev; t->next->prev = t; t->prev->next = t; adb_mutex_unlock(&transport_lock); t->disconnects.next = t->disconnects.prev = &t->disconnects; update_transports(); }
static void transport_registration_func(int _fd, unsigned ev, void *data) { tmsg m; adb_thread_t output_thread_ptr; adb_thread_t input_thread_ptr; int s[2]; atransport *t; if(!(ev & FDE_READ)) { return; } if(transport_read_action(_fd, &m)) { fatal_errno("cannot read transport registration socket"); } t = m.transport; //action0 ÒƳý action1 ²åÈë if(m.action == 0) { D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket); /* IMPORTANT: the remove closes one half of the ** socket pair. The close closes the other half. */ fdevent_remove(&(t->transport_fde)); adb_close(t->fd); adb_mutex_lock(&transport_lock); t->next->prev = t->prev; t->prev->next = t->next; adb_mutex_unlock(&transport_lock); run_transport_disconnects(t); if (t->product) free(t->product); if (t->serial) free(t->serial); if (t->model) free(t->model); if (t->device) free(t->device); if (t->devpath) free(t->devpath); memset(t,0xee,sizeof(atransport)); free(t); update_transports(); return; } /* don't create transport threads for inaccessible devices */ if (t->connection_state != CS_NOPERM) { /* initial references are the two threads */ t->ref_count = 2; if(adb_socketpair(s)) { fatal_errno("cannot open transport socketpair"); } D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); t->transport_socket = s[0]; t->fd = s[1]; fdevent_install(&(t->transport_fde), t->transport_socket, transport_socket_events, t); fdevent_set(&(t->transport_fde), FDE_READ); if(adb_thread_create(&input_thread_ptr, input_thread, t)){ fatal_errno("cannot create input thread"); } if(adb_thread_create(&output_thread_ptr, output_thread, t)){ fatal_errno("cannot create output thread"); } } adb_mutex_lock(&transport_lock); /* remove from pending list */ t->next->prev = t->prev; t->prev->next = t->next; /* put us on the master device list */ t->next = &transport_list; t->prev = transport_list.prev; t->next->prev = t; t->prev->next = t; adb_mutex_unlock(&transport_lock); t->disconnects.next = t->disconnects.prev = &t->disconnects; update_transports(); }
static void transport_registration_func(int _fd, unsigned ev, void *data) { tmsg m; int s[2]; atransport *t; if(!(ev & FDE_READ)) { return; } if(transport_read_action(_fd, &m)) { fatal_errno("cannot read transport registration socket"); } t = m.transport; if (m.action == 0) { D("transport: %s removing and free'ing %d", t->serial, t->transport_socket); /* IMPORTANT: the remove closes one half of the ** socket pair. The close closes the other half. */ fdevent_remove(&(t->transport_fde)); adb_close(t->fd); adb_mutex_lock(&transport_lock); transport_list.remove(t); adb_mutex_unlock(&transport_lock); if (t->product) free(t->product); if (t->serial) free(t->serial); if (t->model) free(t->model); if (t->device) free(t->device); if (t->devpath) free(t->devpath); delete t; update_transports(); return; } /* don't create transport threads for inaccessible devices */ if (t->connection_state != kCsNoPerm) { /* initial references are the two threads */ t->ref_count = 2; if (adb_socketpair(s)) { fatal_errno("cannot open transport socketpair"); } D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]); t->transport_socket = s[0]; t->fd = s[1]; fdevent_install(&(t->transport_fde), t->transport_socket, transport_socket_events, t); fdevent_set(&(t->transport_fde), FDE_READ); if (!adb_thread_create(write_transport_thread, t)) { fatal_errno("cannot create write_transport thread"); } if (!adb_thread_create(read_transport_thread, t)) { fatal_errno("cannot create read_transport thread"); } } adb_mutex_lock(&transport_lock); pending_list.remove(t); transport_list.push_front(t); adb_mutex_unlock(&transport_lock); update_transports(); }
static install_status_t install_listener(const char *local_name, const char *connect_to, atransport* transport, int no_rebind) { alistener *l; D("install_listener('%s','%s')\n", local_name, connect_to); for(l = listener_list.next; l != &listener_list; l = l->next){ if(strcmp(local_name, l->local_name) == 0) { char *cto; /* can't repurpose a smartsocket */ if(l->connect_to[0] == '*') { return INSTALL_STATUS_INTERNAL_ERROR; } /* can't repurpose a listener if 'no_rebind' is true */ if (no_rebind) { return INSTALL_STATUS_CANNOT_REBIND; } cto = strdup(connect_to); if(cto == 0) { return INSTALL_STATUS_INTERNAL_ERROR; } D("rebinding '%s' to '%s'\n", local_name, connect_to); free((void*) l->connect_to); l->connect_to = cto; if (l->transport != transport) { remove_transport_disconnect(l->transport, &l->disconnect); l->transport = transport; add_transport_disconnect(l->transport, &l->disconnect); } return INSTALL_STATUS_OK; } } if((l = (alistener*)calloc(1, sizeof(alistener))) == 0) goto nomem; if((l->local_name = strdup(local_name)) == 0) goto nomem; if((l->connect_to = strdup(connect_to)) == 0) goto nomem; D("LOCAL NAME: %s\n", local_name); l->fd = local_name_to_fd(local_name); D("l->fd: %d\n", l->fd); if(l->fd < 0) { free((void*) l->local_name); free((void*) l->connect_to); free(l); D("cannot bind '%s'\n", local_name); return INSTALL_STATUS_CANNOT_BIND; } close_on_exec(l->fd); if(!strcmp(l->connect_to, "*smartsocket*")) { fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); } else { fdevent_install(&l->fde, l->fd, listener_event_func, l); } fdevent_set(&l->fde, FDE_READ); l->next = &listener_list; l->prev = listener_list.prev; l->next->prev = l; l->prev->next = l; l->transport = transport; if (transport) { l->disconnect.opaque = l; l->disconnect.func = listener_disconnect; add_transport_disconnect(transport, &l->disconnect); } return INSTALL_STATUS_OK; nomem: fatal("cannot allocate listener"); return INSTALL_STATUS_INTERNAL_ERROR; }
FdHandler(int read_fd, int write_fd) : read_fd_(read_fd), write_fd_(write_fd) { fdevent_install(&read_fde_, read_fd_, FdEventCallback, this); fdevent_add(&read_fde_, FDE_READ); fdevent_install(&write_fde_, write_fd_, FdEventCallback, this); }
install_status_t install_listener(const char *local_name, const char *connect_to, atransport* transport, int no_rebind) { for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { if (strcmp(local_name, l->local_name) == 0) { char* cto; /* can't repurpose a smartsocket */ if(l->connect_to[0] == '*') { return INSTALL_STATUS_INTERNAL_ERROR; } /* can't repurpose a listener if 'no_rebind' is true */ if (no_rebind) { return INSTALL_STATUS_CANNOT_REBIND; } cto = strdup(connect_to); if(cto == 0) { return INSTALL_STATUS_INTERNAL_ERROR; } free((void*) l->connect_to); l->connect_to = cto; if (l->transport != transport) { remove_transport_disconnect(l->transport, &l->disconnect); l->transport = transport; add_transport_disconnect(l->transport, &l->disconnect); } return INSTALL_STATUS_OK; } } alistener* listener = reinterpret_cast<alistener*>( calloc(1, sizeof(alistener))); if (listener == nullptr) { goto nomem; } listener->local_name = strdup(local_name); if (listener->local_name == nullptr) { goto nomem; } listener->connect_to = strdup(connect_to); if (listener->connect_to == nullptr) { goto nomem; } listener->fd = local_name_to_fd(local_name); if (listener->fd < 0) { free(listener->local_name); free(listener->connect_to); free(listener); printf("cannot bind '%s'\n", local_name); return INSTALL_STATUS_CANNOT_BIND; } close_on_exec(listener->fd); if (!strcmp(listener->connect_to, "*smartsocket*")) { fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener); } else { fdevent_install(&listener->fde, listener->fd, listener_event_func, listener); } fdevent_set(&listener->fde, FDE_READ); listener->next = &listener_list; listener->prev = listener_list.prev; listener->next->prev = listener; listener->prev->next = listener; listener->transport = transport; if (transport) { listener->disconnect.opaque = listener; listener->disconnect.func = listener_disconnect; add_transport_disconnect(transport, &listener->disconnect); } return INSTALL_STATUS_OK; nomem: fatal("cannot allocate listener"); return INSTALL_STATUS_INTERNAL_ERROR; }