コード例 #1
0
ファイル: oslib-win32.c プロジェクト: Acidburn0zzz/qemu
static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
                     GPollFD *fds, guint nfds, gint timeout)
{
    DWORD ready;
    GPollFD *f;
    int recursed_result;

    if (poll_msgs) {
        /* Wait for either messages or handles
         * -> Use MsgWaitForMultipleObjectsEx
         */
        ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
                                            QS_ALLINPUT, MWMO_ALERTABLE);

        if (ready == WAIT_FAILED) {
            gchar *emsg = g_win32_error_message(GetLastError());
            g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
            g_free(emsg);
        }
    } else if (nhandles == 0) {
        /* No handles to wait for, just the timeout */
        if (timeout == INFINITE) {
            ready = WAIT_FAILED;
        } else {
            SleepEx(timeout, TRUE);
            ready = WAIT_TIMEOUT;
        }
    } else {
        /* Wait for just handles
         * -> Use WaitForMultipleObjectsEx
         */
        ready =
            WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
        if (ready == WAIT_FAILED) {
            gchar *emsg = g_win32_error_message(GetLastError());
            g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
            g_free(emsg);
        }
    }

    if (ready == WAIT_FAILED) {
        return -1;
    } else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
        return 0;
    } else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
        for (f = fds; f < &fds[nfds]; ++f) {
            if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
                f->revents |= G_IO_IN;
            }
        }

        /* If we have a timeout, or no handles to poll, be satisfied
         * with just noticing we have messages waiting.
         */
        if (timeout != 0 || nhandles == 0) {
            return 1;
        }

        /* If no timeout and handles to poll, recurse to poll them,
         * too.
         */
        recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
        return (recursed_result == -1) ? -1 : 1 + recursed_result;
    } else if (/* QEMU: removed the following unneeded statement which causes
                * a compiler warning: ready >= WAIT_OBJECT_0 && */
               ready < WAIT_OBJECT_0 + nhandles) {
        for (f = fds; f < &fds[nfds]; ++f) {
            if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
                f->revents = f->events;
            }
        }

        /* If no timeout and polling several handles, recurse to poll
         * the rest of them.
         */
        if (timeout == 0 && nhandles > 1) {
            /* Remove the handle that fired */
            int i;
            if (ready < nhandles - 1) {
                for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
                    handles[i-1] = handles[i];
                }
            }
            nhandles--;
            recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
            return (recursed_result == -1) ? -1 : 1 + recursed_result;
        }
        return 1;
    }

    return 0;
}
コード例 #2
0
ファイル: oslib-win32.c プロジェクト: Acidburn0zzz/qemu
gint g_poll(GPollFD *fds, guint nfds, gint timeout)
{
    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
    gboolean poll_msgs = FALSE;
    GPollFD *f;
    gint nhandles = 0;
    int retval;

    for (f = fds; f < &fds[nfds]; ++f) {
        if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
            poll_msgs = TRUE;
        } else if (f->fd > 0) {
            /* Don't add the same handle several times into the array, as
             * docs say that is not allowed, even if it actually does seem
             * to work.
             */
            gint i;

            for (i = 0; i < nhandles; i++) {
                if (handles[i] == (HANDLE) f->fd) {
                    break;
                }
            }

            if (i == nhandles) {
                if (nhandles == MAXIMUM_WAIT_OBJECTS) {
                    g_warning("Too many handles to wait for!\n");
                    break;
                } else {
                    handles[nhandles++] = (HANDLE) f->fd;
                }
            }
        }
    }

    for (f = fds; f < &fds[nfds]; ++f) {
        f->revents = 0;
    }

    if (timeout == -1) {
        timeout = INFINITE;
    }

    /* Polling for several things? */
    if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
        /* First check if one or several of them are immediately
         * available
         */
        retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);

        /* If not, and we have a significant timeout, poll again with
         * timeout then. Note that this will return indication for only
         * one event, or only for messages. We ignore timeouts less than
         * ten milliseconds as they are mostly pointless on Windows, the
         * MsgWaitForMultipleObjectsEx() call will timeout right away
         * anyway.
         *
         * Modification for QEMU: replaced timeout >= 10 by timeout > 0.
         */
        if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
            retval = poll_rest(poll_msgs, handles, nhandles,
                               fds, nfds, timeout);
        }
    } else {
        /* Just polling for one thing, so no need to check first if
         * available immediately
         */
        retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
    }

    if (retval == -1) {
        for (f = fds; f < &fds[nfds]; ++f) {
            f->revents = 0;
        }
    }

    return retval;
}
コード例 #3
0
ファイル: gpoll.c プロジェクト: caomw/glib-1
gint
g_poll (GPollFD *fds,
	guint    nfds,
	gint     timeout)
{
  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
  gboolean poll_msgs = FALSE;
  GPollFD *f;
  gint nhandles = 0;
  int retval;

  if (_g_main_poll_debug)
    g_print ("g_poll: waiting for");

  for (f = fds; f < &fds[nfds]; ++f)
    if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN))
      {
	if (_g_main_poll_debug && !poll_msgs)
	  g_print (" MSG");
	poll_msgs = TRUE;
      }
    else if (f->fd > 0)
      {
        if (nhandles == MAXIMUM_WAIT_OBJECTS)
          {
            g_warning ("Too many handles to wait for!\n");
            break;
          }
        else
          {
            if (_g_main_poll_debug)
              g_print (" %p", (HANDLE) f->fd);
            handles[nhandles++] = (HANDLE) f->fd;
          }
      }

  if (_g_main_poll_debug)
    g_print ("\n");

  for (f = fds; f < &fds[nfds]; ++f)
    f->revents = 0;

  if (timeout == -1)
    timeout = INFINITE;

  /* Polling for several things? */
  if (nhandles > 1 || (nhandles > 0 && poll_msgs))
    {
      /* First check if one or several of them are immediately
       * available
       */
      retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, 0);

      /* If not, and we have a significant timeout, poll again with
       * timeout then. Note that this will return indication for only
       * one event, or only for messages.
       */
      if (retval == 0 && (timeout == INFINITE || timeout > 0))
	retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
    }
  else
    {
      /* Just polling for one thing, so no need to check first if
       * available immediately
       */
      retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
    }

  if (retval == -1)
    for (f = fds; f < &fds[nfds]; ++f)
      f->revents = 0;

  return retval;
}