Esempio n. 1
0
int sim_slirp_select (SLIRP *slirp, int ms_timeout)
{
int select_ret = 0;
uint32 slirp_timeout = ms_timeout;
struct timeval timeout;
fd_set rfds, wfds, xfds;
fd_set save_rfds, save_wfds, save_xfds;
int nfds;

/* Populate the GPollFDs from slirp */
g_array_set_size (slirp->gpollfds, 1);  /* Leave the doorbell chime alone */
slirp_pollfds_fill(slirp->gpollfds, &slirp_timeout);
timeout.tv_sec  = slirp_timeout / 1000;
timeout.tv_usec = (slirp_timeout % 1000) * 1000;

FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
/* Extract the GPollFDs interest */
nfds = pollfds_fill (slirp->gpollfds, &rfds, &wfds, &xfds);
save_rfds = rfds;
save_wfds = wfds;
save_xfds = xfds;
select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &timeout);
if (select_ret) {
    int i;
    /* Update the GPollFDs results */
    pollfds_poll (slirp->gpollfds, nfds, &rfds, &wfds, &xfds);
    if (FD_ISSET (slirp->db_chime, &rfds)) {
        char buf[32];
        /* consume the doorbell wakeup ring */
        recv (slirp->db_chime, buf, sizeof (buf), 0);
        }
    sim_debug (slirp->dbit, slirp->dptr, "Select returned %d\r\n", select_ret);
    for (i=0; i<nfds+1; i++) {
        if (FD_ISSET(i, &rfds) || FD_ISSET(i, &save_rfds))
            sim_debug (slirp->dbit, slirp->dptr, "%d: save_rfd=%d, rfd=%d\r\n", i, FD_ISSET(i, &save_rfds), FD_ISSET(i, &rfds));
        if (FD_ISSET(i, &wfds) || FD_ISSET(i, &save_wfds))
            sim_debug (slirp->dbit, slirp->dptr, "%d: save_wfd=%d, wfd=%d\r\n", i, FD_ISSET(i, &save_wfds), FD_ISSET(i, &wfds));
        if (FD_ISSET(i, &xfds) || FD_ISSET(i, &save_xfds))
            sim_debug (slirp->dbit, slirp->dptr, "%d: save_xfd=%d, xfd=%d\r\n", i, FD_ISSET(i, &save_xfds), FD_ISSET(i, &xfds));
            }
    }
return select_ret + 1;  /* Force dispatch even on timeout */
}
Esempio n. 2
0
static int os_host_main_loop_wait(int64_t timeout)
{
    GMainContext *context = g_main_context_default();
    GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
    int select_ret = 0;
    int g_poll_ret, ret, i, n_poll_fds;
    PollingEntry *pe;
    WaitObjects *w = &wait_objects;
    gint poll_timeout;
    int64_t poll_timeout_ns;
    static struct timeval tv0;
    fd_set rfds, wfds, xfds;
    int nfds;

    /* XXX: need to suppress polling by better using win32 events */
    ret = 0;
    for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
        ret |= pe->func(pe->opaque);
    }
    if (ret != 0) {
        return ret;
    }

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&xfds);
    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
    if (nfds >= 0) {
        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
        if (select_ret != 0) {
            timeout = 0;
        }
        if (select_ret > 0) {
            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
        }
    }

    g_main_context_prepare(context, &max_priority);
    n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
                                      poll_fds, ARRAY_SIZE(poll_fds));
    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));

    for (i = 0; i < w->num; i++) {
        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
        poll_fds[n_poll_fds + i].events = G_IO_IN;
    }

    if (poll_timeout < 0) {
        poll_timeout_ns = -1;
    } else {
        poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
    }

    poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);

    qemu_mutex_unlock_iothread();
    g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);

    qemu_mutex_lock_iothread();
    if (g_poll_ret > 0) {
        for (i = 0; i < w->num; i++) {
            w->revents[i] = poll_fds[n_poll_fds + i].revents;
        }
        for (i = 0; i < w->num; i++) {
            if (w->revents[i] && w->func[i]) {
                w->func[i](w->opaque[i]);
            }
        }
    }

    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
        g_main_context_dispatch(context);
    }

    return select_ret || g_poll_ret;
}