Exemple #1
0
void fdevent_set(fdevent *fde, unsigned events)
{
    printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__);
    events &= FDE_EVENTMASK;

    if((fde->state & FDE_EVENTMASK) == events) return;

    if(fde->state & FDE_ACTIVE) {
        fdevent_update(fde, events);
        dump_fde(fde, "update");
    }

    fde->state = (fde->state & FDE_STATEMASK) | events;

    if(fde->state & FDE_PENDING) {
            /* if we're pending, make sure
            ** we don't signal an event that
            ** is no longer wanted.
            */
        fde->events &= (~events);
        if(fde->events == 0) {
            fdevent_plist_remove(fde);
            fde->state &= (~FDE_PENDING);
        }
    }
}
void fdevent_set(fdevent *fde, unsigned events)
{
    events &= FDE_EVENTMASK;

    if((fde->state & FDE_EVENTMASK) == (int)events) return;

    if(fde->state & FDE_ACTIVE) {
        fdevent_update(fde, events);
        dump_fde(fde, "update");
    }

    fde->state = (fde->state & FDE_STATEMASK) | events;

    if(fde->state & FDE_PENDING) {
            /* if we're pending, make sure
            ** we don't signal an event that
            ** is no longer wanted.
            */
        fde->events &= (~events);
        if(fde->events == 0) {
            fdevent_plist_remove(fde);
            fde->state &= (~FDE_PENDING);
        }
    }
}
Exemple #3
0
static void fdevent_call_fdfunc(fdevent* fde) {
    unsigned events = fde->events;
    fde->events = 0;
    if(!(fde->state & FDE_PENDING)) return;
    fde->state &= (~FDE_PENDING);
    dump_fde(fde, "callback");
    fde->func(fde->fd, events, fde->arg);
}
static void fdevent_call_fdfunc(fdevent* fde)
{
    unsigned events = fde->events;
    fde->events = 0;
    CHECK(fde->state & FDE_PENDING);
    fde->state &= (~FDE_PENDING);
    D("fdevent_call_fdfunc %s", dump_fde(fde).c_str());
    fde->func(fde->fd, events, fde->arg);
}
void fdevent_destroy(fdevent *fde)
{
    if(fde == 0) return;
    if(!(fde->state & FDE_CREATED)) {
        LOG(FATAL) << "destroying fde not created by fdevent_create(): " << dump_fde(fde);
    }
    fdevent_remove(fde);
    free(fde);
}
Exemple #6
0
static void fdevent_call_fdfunc(fdevent* fde)
{
    unsigned events = fde->events;
    fde->events = 0;
    if(!(fde->state & FDE_PENDING)) return;
    fde->state &= (~FDE_PENDING);
    printf("function = %s, file = %s, line = %u, fde = %p, fde->func = %p \n", __FUNCTION__, __FILE__, __LINE__, fde, fde->func);
    dump_fde(fde, "callback");
    fde->func(fde->fd, events, fde->arg);
}
void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 
{
    memset(fde, 0, sizeof(fdevent));
    fde->state = FDE_ACTIVE;
    fde->fd = fd;
    fde->func = func;
    fde->arg = arg;

    fdevent_register(fde);
    dump_fde(fde, "connect");
    fdevent_connect(fde);
    fde->state |= FDE_ACTIVE;
}
Exemple #8
0
void fdevent_remove(fdevent *fde) {
    if(fde->state & FDE_PENDING) {
        fdevent_plist_remove(fde);
    }

    if(fde->state & FDE_ACTIVE) {
        fdevent_disconnect(fde);
        dump_fde(fde, "disconnect");
        fdevent_unregister(fde);
    }

    fde->state = 0;
    fde->events = 0;
}
void fdevent_remove(fdevent* fde) {
    D("fdevent_remove %s", dump_fde(fde).c_str());
    if (fde->state & FDE_ACTIVE) {
        g_poll_node_map.erase(fde->fd);
        if (fde->state & FDE_PENDING) {
            g_pending_list.remove(fde);
        }
        if (!(fde->state & FDE_DONT_CLOSE)) {
            adb_close(fde->fd);
            fde->fd = -1;
        }
        fde->state = 0;
        fde->events = 0;
    }
}
Exemple #10
0
void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 
{
    memset(fde, 0, sizeof(fdevent));
    fde->state = FDE_ACTIVE;
    fde->fd = fd;
    fde->func = func;
    fde->arg = arg;

#ifndef HAVE_WINSOCK
    fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
    fdevent_register(fde);
    dump_fde(fde, "connect");
    fdevent_connect(fde);
    fde->state |= FDE_ACTIVE;
}
Exemple #11
0
static void fdevent_unregister(fdevent *fde) {
    if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
        FATAL("fd out of range (%d)\n", fde->fd);
    }

    if(fd_table[fde->fd] != fde) {
        FATAL("fd_table out of sync [%d]\n", fde->fd);
    }

    fd_table[fde->fd] = 0;

    if(!(fde->state & FDE_DONT_CLOSE)) {
        dump_fde(fde, "close");
        adb_close(fde->fd);
    }
}
Exemple #12
0
void fdevent_remove(fdevent *fde)
{
    printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__);
    if(fde->state & FDE_PENDING) {
        fdevent_plist_remove(fde);
    }

    if(fde->state & FDE_ACTIVE) {
        fdevent_disconnect(fde);
        dump_fde(fde, "disconnect");
        fdevent_unregister(fde);
    }

    fde->state = 0;
    fde->events = 0;
}
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_install(fdevent* fde, int fd, fd_func func, void* arg) {
    CHECK_GE(fd, 0);
    memset(fde, 0, sizeof(fdevent));
    fde->state = FDE_ACTIVE;
    fde->fd = fd;
    fde->func = func;
    fde->arg = arg;
    if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) {
        // Here is not proper to handle the error. If it fails here, some error is
        // likely to be detected by poll(), then we can let the callback function
        // to handle it.
        LOG(ERROR) << "failed to fcntl(" << fd << ") to be nonblock";
    }
    auto pair = g_poll_node_map.emplace(fde->fd, PollNode(fde));
    CHECK(pair.second) << "install existing fd " << fd;
    D("fdevent_install %s", dump_fde(fde).c_str());
}
static void fdevent_process() {
    std::vector<pollfd> pollfds;
    for (auto it = g_poll_node_map.begin(); it != g_poll_node_map.end(); ++it) {
        pollfds.push_back(it->second.pollfd);
    }
    CHECK_GT(pollfds.size(), 0u);
    D("poll(), pollfds = %s", dump_pollfds(pollfds).c_str());
    int ret = TEMP_FAILURE_RETRY(poll(&pollfds[0], pollfds.size(), -1));
    if (ret == -1) {
        PLOG(ERROR) << "poll(), ret = " << ret;
        return;
    }
    for (auto& pollfd : pollfds) {
        if (pollfd.revents != 0) {
            D("for fd %d, revents = %x", pollfd.fd, pollfd.revents);
        }
        unsigned events = 0;
        if (pollfd.revents & POLLIN) {
            events |= FDE_READ;
        }
        if (pollfd.revents & POLLOUT) {
            events |= FDE_WRITE;
        }
        if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
            // We fake a read, as the rest of the code assumes that errors will
            // be detected at that point.
            events |= FDE_READ | FDE_ERROR;
        }
#if defined(__linux__)
        if (pollfd.revents & POLLRDHUP) {
            events |= FDE_READ | FDE_ERROR;
        }
#endif
        if (events != 0) {
            auto it = g_poll_node_map.find(pollfd.fd);
            CHECK(it != g_poll_node_map.end());
            fdevent* fde = it->second.fde;
            CHECK_EQ(fde->fd, pollfd.fd);
            fde->events |= events;
            D("%s got events %x", dump_fde(fde).c_str(), events);
            fde->state |= FDE_PENDING;
            g_pending_list.push_back(fde);
        }
    }
}
Exemple #16
0
static void fdevent_unregister(fdevent *fde)
{
    printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__);
    if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
        FATAL("fd out of range (%d)\n", fde->fd);
    }

    if(fd_table[fde->fd] != fde) {
        FATAL("fd_table out of sync [%d]\n", fde->fd);
    }

    fd_table[fde->fd] = 0;

    if(!(fde->state & FDE_DONT_CLOSE)) {
        dump_fde(fde, "close");
        adb_close(fde->fd);
    }
}
void fdevent_set(fdevent* fde, unsigned events) {
    events &= FDE_EVENTMASK;
    if ((fde->state & FDE_EVENTMASK) == events) {
        return;
    }
    CHECK(fde->state & FDE_ACTIVE);
    fdevent_update(fde, events);
    D("fdevent_set: %s, events = %u", dump_fde(fde).c_str(), events);

    if (fde->state & FDE_PENDING) {
        // If we are pending, make sure we don't signal an event that is no longer wanted.
        fde->events &= events;
        if (fde->events == 0) {
            g_pending_list.remove(fde);
            fde->state &= ~FDE_PENDING;
        }
    }
}
void fdevent_loop()
{
    fdevent *fde;

    for(;;) {
#if DEBUG
        fprintf(stderr,"--- ---- waiting for events\n");
#endif
        fdevent_process();

        while((fde = fdevent_plist_dequeue())) {
            unsigned events = fde->events;
            fde->events = 0;
            fde->state &= (~FDE_PENDING);
            dump_fde(fde, "callback");
            fde->func(fde->fd, events, fde->arg);
        }
    }
}
Exemple #19
0
void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
{
    printf("function = %s, file = %s, line = %u, fde = %p,  fd = %d, func = %p \n", __FUNCTION__, __FILE__, __LINE__, fde, fd, func);
    memset(fde, 0, sizeof(fdevent));
    fde->state = FDE_ACTIVE;
    fde->fd = fd;
    fde->force_eof = 0;
    fde->func = func;
    fde->arg = arg;

#ifndef HAVE_WINSOCK
    fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
    printf("function = %s, file = %s, line = %u, before fdevent_register \n", __FUNCTION__, __FILE__, __LINE__);
    fdevent_register(fde);
    dump_fde(fde, "connect");
    printf("function = %s, file = %s, line = %u, after fdevent_register and before fdevent_connect \n", __FUNCTION__, __FILE__, __LINE__);
    fdevent_connect(fde);
    fde->state |= FDE_ACTIVE;
}