Example #1
0
void init_transport_registration(void)
{
	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,
		0);

	fdevent_set(&transport_registration_fde, FDE_READ);
}
static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
{
    D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
#if defined(_WIN32)
    fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
    return -1;
#else

    // 0 is parent socket, 1 is child socket
    int sv[2];
    if (adb_socketpair(sv) < 0) {
        printf("[ cannot create socket pair - %s ]\n", strerror(errno));
        return -1;
    }
    D("socketpair: (%d,%d)", sv[0], sv[1]);

    *pid = fork();
    if (*pid < 0) {
        printf("- fork failed: %s -\n", strerror(errno));
        adb_close(sv[0]);
        adb_close(sv[1]);
        return -1;
    }

    if (*pid == 0) {
        adb_close(sv[0]);
        init_subproc_child();

        dup2(sv[1], STDIN_FILENO);
        dup2(sv[1], STDOUT_FILENO);
        dup2(sv[1], STDERR_FILENO);

        adb_close(sv[1]);

        execl(cmd, cmd, arg0, arg1, NULL);
        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                cmd, strerror(errno), errno);
        exit(-1);
    } else {
        adb_close(sv[1]);
        return sv[0];
    }
#endif /* !defined(_WIN32) */
}
// This test checks when a local socket doesn't enable FDE_READ/FDE_WRITE/FDE_ERROR, it
// can still be closed when some error happens on its file handler.
// This test successes on linux but fails on mac because of different implementation of
// poll(). I think the function tested here is useful to make adb server more stable on
// linux.
TEST_F(LocalSocketTest, close_with_no_events_installed) {
    int socket_fd[2];
    ASSERT_EQ(0, adb_socketpair(socket_fd));

    CloseNoEventsArg arg;
    arg.socket_fd = socket_fd[1];
    pthread_t thread;
    ASSERT_EQ(0, pthread_create(&thread, nullptr,
                                reinterpret_cast<void* (*)(void*)>(CloseNoEventsThreadFunc),
                                &arg));
    // Wait until the fdevent_loop() starts.
    sleep(1);
    ASSERT_EQ(2u, fdevent_installed_count());
    ASSERT_EQ(0, adb_close(socket_fd[0]));

    // Wait until the socket is closed.
    sleep(1);

    ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
    ASSERT_EQ(0, pthread_join(thread, nullptr));
}
int
create_jdwp_connection_fd(int  pid)
{
    JdwpProcess*  proc = _jdwp_list.next;

    D("looking for pid %d in JDWP process list\n", pid);
    for ( ; proc != &_jdwp_list; proc = proc->next ) {
        if (proc->pid == pid) {
            goto FoundIt;
        }
    }
    D("search failed !!\n");
    return -1;

FoundIt:
    {
        int  fds[2];

        if (proc->out_count >= MAX_OUT_FDS) {
            D("%s: too many pending JDWP connection for pid %d\n",
              __FUNCTION__, pid);
            return -1;
        }

        if (adb_socketpair(fds) < 0) {
            D("%s: socket pair creation failed: %s\n",
              __FUNCTION__, strerror(errno));
            return -1;
        }
        D("socketpair: (%d,%d)", fds[0], fds[1]);

        proc->out_fds[ proc->out_count ] = fds[1];
        if (++proc->out_count == 1)
            fdevent_add( proc->fde, FDE_WRITE );

        return fds[0];
    }
}
unique_fd create_jdwp_connection_fd(int pid) {
    D("looking for pid %d in JDWP process list", pid);

    for (auto& proc : _jdwp_list) {
        if (proc->pid == pid) {
            int fds[2];

            if (adb_socketpair(fds) < 0) {
                D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
                return unique_fd{};
            }
            D("socketpair: (%d,%d)", fds[0], fds[1]);

            proc->out_fds.emplace_back(fds[1]);
            if (proc->out_fds.size() == 1) {
                fdevent_add(proc->fde, FDE_WRITE);
            }

            return unique_fd{fds[0]};
        }
    }
    D("search failed !!");
    return unique_fd{};
}
Example #6
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();
}
Example #7
0
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();
}
 void SetUp() override {
     ASSERT_EQ(0, adb_socketpair(fds)) << strerror(errno);
 }
Example #10
0
 DLL_EXPORT void socket_pipe(int sv[2]) {
   adb_socketpair(sv);
 }
void BM_Connection_Echo(benchmark::State& state) {
    int fds[2];
    if (adb_socketpair(fds) != 0) {
        LOG(FATAL) << "failed to create socketpair";
    }

    auto client = MakeConnection<ConnectionType>(unique_fd(fds[0]));
    auto server = MakeConnection<ConnectionType>(unique_fd(fds[1]));

    std::atomic<size_t> received_bytes;

    fdevent_reset();
    std::thread fdevent_thread([]() { fdevent_loop(); });

    client->SetReadCallback([&received_bytes](Connection*, std::unique_ptr<apacket> packet) -> bool {
        received_bytes += packet->payload.size();
        return true;
    });

    static const auto handle_packet = [](Connection* connection, std::unique_ptr<apacket> packet) {
        connection->Write(std::move(packet));
    };

    server->SetReadCallback([](Connection* connection, std::unique_ptr<apacket> packet) -> bool {
        if (Policy == ThreadPolicy::MainThread) {
            auto raw_packet = packet.release();
            fdevent_run_on_main_thread([connection, raw_packet]() {
                std::unique_ptr<apacket> packet(raw_packet);
                handle_packet(connection, std::move(packet));
            });
        } else {
            handle_packet(connection, std::move(packet));
        }
        return true;
    });

    client->SetErrorCallback(
        [](Connection*, const std::string& error) { LOG(INFO) << "client closed: " << error; });
    server->SetErrorCallback(
        [](Connection*, const std::string& error) { LOG(INFO) << "server closed: " << error; });

    client->Start();
    server->Start();

    for (auto _ : state) {
        size_t data_size = state.range(0);
        std::unique_ptr<apacket> packet = std::make_unique<apacket>();
        memset(&packet->msg, 0, sizeof(packet->msg));
        packet->msg.command = A_WRTE;
        packet->msg.data_length = data_size;
        packet->payload.resize(data_size);

        memset(&packet->payload[0], 0xff, data_size);

        received_bytes = 0;
        client->Write(std::move(packet));
        while (received_bytes < data_size) {
            continue;
        }
    }
    state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) * state.range(0));

    client->Stop();
    server->Stop();

    // TODO: Make it so that you don't need to poke the fdevent loop to make it terminate?
    fdevent_terminate_loop();
    fdevent_run_on_main_thread([]() {});

    fdevent_thread.join();
}