qemu/main-loop.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu-common.h"
  26#include "qemu-timer.h"
  27#include "slirp/slirp.h"
  28#include "main-loop.h"
  29
  30#ifndef _WIN32
  31
  32#include "compatfd.h"
  33
  34static int io_thread_fd = -1;
  35
  36void qemu_notify_event(void)
  37{
  38    /* Write 8 bytes to be compatible with eventfd.  */
  39    static const uint64_t val = 1;
  40    ssize_t ret;
  41
  42    if (io_thread_fd == -1) {
  43        return;
  44    }
  45    do {
  46        ret = write(io_thread_fd, &val, sizeof(val));
  47    } while (ret < 0 && errno == EINTR);
  48
  49    /* EAGAIN is fine, a read must be pending.  */
  50    if (ret < 0 && errno != EAGAIN) {
  51        fprintf(stderr, "qemu_notify_event: write() failed: %s\n",
  52                strerror(errno));
  53        exit(1);
  54    }
  55}
  56
  57static void qemu_event_read(void *opaque)
  58{
  59    int fd = (intptr_t)opaque;
  60    ssize_t len;
  61    char buffer[512];
  62
  63    /* Drain the notify pipe.  For eventfd, only 8 bytes will be read.  */
  64    do {
  65        len = read(fd, buffer, sizeof(buffer));
  66    } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
  67}
  68
  69static int qemu_event_init(void)
  70{
  71    int err;
  72    int fds[2];
  73
  74    err = qemu_eventfd(fds);
  75    if (err == -1) {
  76        return -errno;
  77    }
  78    err = fcntl_setfl(fds[0], O_NONBLOCK);
  79    if (err < 0) {
  80        goto fail;
  81    }
  82    err = fcntl_setfl(fds[1], O_NONBLOCK);
  83    if (err < 0) {
  84        goto fail;
  85    }
  86    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
  87                         (void *)(intptr_t)fds[0]);
  88
  89    io_thread_fd = fds[1];
  90    return 0;
  91
  92fail:
  93    close(fds[0]);
  94    close(fds[1]);
  95    return err;
  96}
  97
  98/* If we have signalfd, we mask out the signals we want to handle and then
  99 * use signalfd to listen for them.  We rely on whatever the current signal
 100 * handler is to dispatch the signals when we receive them.
 101 */
 102static void sigfd_handler(void *opaque)
 103{
 104    int fd = (intptr_t)opaque;
 105    struct qemu_signalfd_siginfo info;
 106    struct sigaction action;
 107    ssize_t len;
 108
 109    while (1) {
 110        do {
 111            len = read(fd, &info, sizeof(info));
 112        } while (len == -1 && errno == EINTR);
 113
 114        if (len == -1 && errno == EAGAIN) {
 115            break;
 116        }
 117
 118        if (len != sizeof(info)) {
 119            printf("read from sigfd returned %zd: %m\n", len);
 120            return;
 121        }
 122
 123        sigaction(info.ssi_signo, NULL, &action);
 124        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
 125            action.sa_sigaction(info.ssi_signo,
 126                                (siginfo_t *)&info, NULL);
 127        } else if (action.sa_handler) {
 128            action.sa_handler(info.ssi_signo);
 129        }
 130    }
 131}
 132
 133static int qemu_signal_init(void)
 134{
 135    int sigfd;
 136    sigset_t set;
 137
 138    /*
 139     * SIG_IPI must be blocked in the main thread and must not be caught
 140     * by sigwait() in the signal thread. Otherwise, the cpu thread will
 141     * not catch it reliably.
 142     */
 143    sigemptyset(&set);
 144    sigaddset(&set, SIG_IPI);
 145    sigaddset(&set, SIGIO);
 146    sigaddset(&set, SIGALRM);
 147    sigaddset(&set, SIGBUS);
 148    pthread_sigmask(SIG_BLOCK, &set, NULL);
 149
 150    sigdelset(&set, SIG_IPI);
 151    sigfd = qemu_signalfd(&set);
 152    if (sigfd == -1) {
 153        fprintf(stderr, "failed to create signalfd\n");
 154        return -errno;
 155    }
 156
 157    fcntl_setfl(sigfd, O_NONBLOCK);
 158
 159    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
 160                         (void *)(intptr_t)sigfd);
 161
 162    return 0;
 163}
 164
 165#else /* _WIN32 */
 166
 167static HANDLE qemu_event_handle = NULL;
 168
 169static void dummy_event_handler(void *opaque)
 170{
 171}
 172
 173static int qemu_event_init(void)
 174{
 175    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
 176    if (!qemu_event_handle) {
 177        fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
 178        return -1;
 179    }
 180    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
 181    return 0;
 182}
 183
 184void qemu_notify_event(void)
 185{
 186    if (!qemu_event_handle) {
 187        return;
 188    }
 189    if (!SetEvent(qemu_event_handle)) {
 190        fprintf(stderr, "qemu_notify_event: SetEvent failed: %ld\n",
 191                GetLastError());
 192        exit(1);
 193    }
 194}
 195
 196static int qemu_signal_init(void)
 197{
 198    return 0;
 199}
 200#endif
 201
 202int main_loop_init(void)
 203{
 204    int ret;
 205
 206    qemu_mutex_lock_iothread();
 207    ret = qemu_signal_init();
 208    if (ret) {
 209        return ret;
 210    }
 211
 212    /* Note eventfd must be drained before signalfd handlers run */
 213    ret = qemu_event_init();
 214    if (ret) {
 215        return ret;
 216    }
 217
 218    return 0;
 219}
 220
 221static fd_set rfds, wfds, xfds;
 222static int nfds;
 223static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 224static int n_poll_fds;
 225static int max_priority;
 226
 227#ifndef _WIN32
 228static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
 229                             fd_set *xfds, uint32_t *cur_timeout)
 230{
 231    GMainContext *context = g_main_context_default();
 232    int i;
 233    int timeout = 0;
 234
 235    g_main_context_prepare(context, &max_priority);
 236
 237    n_poll_fds = g_main_context_query(context, max_priority, &timeout,
 238                                      poll_fds, ARRAY_SIZE(poll_fds));
 239    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
 240
 241    for (i = 0; i < n_poll_fds; i++) {
 242        GPollFD *p = &poll_fds[i];
 243
 244        if ((p->events & G_IO_IN)) {
 245            FD_SET(p->fd, rfds);
 246            *max_fd = MAX(*max_fd, p->fd);
 247        }
 248        if ((p->events & G_IO_OUT)) {
 249            FD_SET(p->fd, wfds);
 250            *max_fd = MAX(*max_fd, p->fd);
 251        }
 252        if ((p->events & G_IO_ERR)) {
 253            FD_SET(p->fd, xfds);
 254            *max_fd = MAX(*max_fd, p->fd);
 255        }
 256    }
 257
 258    if (timeout >= 0 && timeout < *cur_timeout) {
 259        *cur_timeout = timeout;
 260    }
 261}
 262
 263static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
 264                             bool err)
 265{
 266    GMainContext *context = g_main_context_default();
 267
 268    if (!err) {
 269        int i;
 270
 271        for (i = 0; i < n_poll_fds; i++) {
 272            GPollFD *p = &poll_fds[i];
 273
 274            if ((p->events & G_IO_IN) && FD_ISSET(p->fd, rfds)) {
 275                p->revents |= G_IO_IN;
 276            }
 277            if ((p->events & G_IO_OUT) && FD_ISSET(p->fd, wfds)) {
 278                p->revents |= G_IO_OUT;
 279            }
 280            if ((p->events & G_IO_ERR) && FD_ISSET(p->fd, xfds)) {
 281                p->revents |= G_IO_ERR;
 282            }
 283        }
 284    }
 285
 286    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
 287        g_main_context_dispatch(context);
 288    }
 289}
 290
 291static int os_host_main_loop_wait(uint32_t timeout)
 292{
 293    struct timeval tv, *tvarg = NULL;
 294    int ret;
 295
 296    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
 297
 298    if (timeout < UINT32_MAX) {
 299        tvarg = &tv;
 300        tv.tv_sec = timeout / 1000;
 301        tv.tv_usec = (timeout % 1000) * 1000;
 302    }
 303
 304    if (timeout > 0) {
 305        qemu_mutex_unlock_iothread();
 306    }
 307
 308    ret = select(nfds + 1, &rfds, &wfds, &xfds, tvarg);
 309
 310    if (timeout > 0) {
 311        qemu_mutex_lock_iothread();
 312    }
 313
 314    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 315    return ret;
 316}
 317#else
 318/***********************************************************/
 319/* Polling handling */
 320
 321typedef struct PollingEntry {
 322    PollingFunc *func;
 323    void *opaque;
 324    struct PollingEntry *next;
 325} PollingEntry;
 326
 327static PollingEntry *first_polling_entry;
 328
 329int qemu_add_polling_cb(PollingFunc *func, void *opaque)
 330{
 331    PollingEntry **ppe, *pe;
 332    pe = g_malloc0(sizeof(PollingEntry));
 333    pe->func = func;
 334    pe->opaque = opaque;
 335    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
 336    *ppe = pe;
 337    return 0;
 338}
 339
 340void qemu_del_polling_cb(PollingFunc *func, void *opaque)
 341{
 342    PollingEntry **ppe, *pe;
 343    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
 344        pe = *ppe;
 345        if (pe->func == func && pe->opaque == opaque) {
 346            *ppe = pe->next;
 347            g_free(pe);
 348            break;
 349        }
 350    }
 351}
 352
 353/***********************************************************/
 354/* Wait objects support */
 355typedef struct WaitObjects {
 356    int num;
 357    int revents[MAXIMUM_WAIT_OBJECTS + 1];
 358    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
 359    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
 360    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
 361} WaitObjects;
 362
 363static WaitObjects wait_objects = {0};
 364
 365int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 366{
 367    WaitObjects *w = &wait_objects;
 368    if (w->num >= MAXIMUM_WAIT_OBJECTS) {
 369        return -1;
 370    }
 371    w->events[w->num] = handle;
 372    w->func[w->num] = func;
 373    w->opaque[w->num] = opaque;
 374    w->revents[w->num] = 0;
 375    w->num++;
 376    return 0;
 377}
 378
 379void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 380{
 381    int i, found;
 382    WaitObjects *w = &wait_objects;
 383
 384    found = 0;
 385    for (i = 0; i < w->num; i++) {
 386        if (w->events[i] == handle) {
 387            found = 1;
 388        }
 389        if (found) {
 390            w->events[i] = w->events[i + 1];
 391            w->func[i] = w->func[i + 1];
 392            w->opaque[i] = w->opaque[i + 1];
 393            w->revents[i] = w->revents[i + 1];
 394        }
 395    }
 396    if (found) {
 397        w->num--;
 398    }
 399}
 400
 401void qemu_fd_register(int fd)
 402{
 403    WSAEventSelect(fd, qemu_event_handle, FD_READ | FD_ACCEPT | FD_CLOSE |
 404                   FD_CONNECT | FD_WRITE | FD_OOB);
 405}
 406
 407static int os_host_main_loop_wait(uint32_t timeout)
 408{
 409    GMainContext *context = g_main_context_default();
 410    int ret, i;
 411    PollingEntry *pe;
 412    WaitObjects *w = &wait_objects;
 413    gint poll_timeout;
 414    static struct timeval tv0;
 415
 416    /* XXX: need to suppress polling by better using win32 events */
 417    ret = 0;
 418    for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
 419        ret |= pe->func(pe->opaque);
 420    }
 421    if (ret != 0) {
 422        return ret;
 423    }
 424
 425    if (nfds >= 0) {
 426        ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
 427        if (ret != 0) {
 428            timeout = 0;
 429        }
 430    }
 431
 432    g_main_context_prepare(context, &max_priority);
 433    n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
 434                                      poll_fds, ARRAY_SIZE(poll_fds));
 435    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
 436
 437    for (i = 0; i < w->num; i++) {
 438        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
 439        poll_fds[n_poll_fds + i].events = G_IO_IN;
 440    }
 441
 442    if (poll_timeout < 0 || timeout < poll_timeout) {
 443        poll_timeout = timeout;
 444    }
 445
 446    qemu_mutex_unlock_iothread();
 447    ret = g_poll(poll_fds, n_poll_fds + w->num, poll_timeout);
 448    qemu_mutex_lock_iothread();
 449    if (ret > 0) {
 450        for (i = 0; i < w->num; i++) {
 451            w->revents[i] = poll_fds[n_poll_fds + i].revents;
 452        }
 453        for (i = 0; i < w->num; i++) {
 454            if (w->revents[i] && w->func[i]) {
 455                w->func[i](w->opaque[i]);
 456            }
 457        }
 458    }
 459
 460    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
 461        g_main_context_dispatch(context);
 462    }
 463
 464    /* If an edge-triggered socket event occurred, select will return a
 465     * positive result on the next iteration.  We do not need to do anything
 466     * here.
 467     */
 468
 469    return ret;
 470}
 471#endif
 472
 473int main_loop_wait(int nonblocking)
 474{
 475    int ret;
 476    uint32_t timeout = UINT32_MAX;
 477
 478    if (nonblocking) {
 479        timeout = 0;
 480    } else {
 481        qemu_bh_update_timeout(&timeout);
 482    }
 483
 484    /* poll any events */
 485    /* XXX: separate device handlers from system ones */
 486    nfds = -1;
 487    FD_ZERO(&rfds);
 488    FD_ZERO(&wfds);
 489    FD_ZERO(&xfds);
 490
 491#ifdef CONFIG_SLIRP
 492    slirp_update_timeout(&timeout);
 493    slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 494#endif
 495    qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
 496    ret = os_host_main_loop_wait(timeout);
 497    qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
 498#ifdef CONFIG_SLIRP
 499    slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 500#endif
 501
 502    qemu_run_all_timers();
 503
 504    /* Check bottom-halves last in case any of the earlier events triggered
 505       them.  */
 506    qemu_bh_poll();
 507
 508    return ret;
 509}
 510