Patchwork [05/11] main-loop: switch POSIX glib integration to Poller

login
register
mail settings
Submitter Stefan Hajnoczi
Date Jan. 31, 2013, 10:53 a.m.
Message ID <1359629644-21920-6-git-send-email-stefanha@redhat.com>
Download mbox | patch
Permalink /patch/217168/
State New
Headers show

Comments

Stefan Hajnoczi - Jan. 31, 2013, 10:53 a.m.
Convert glib file descriptor polling from rfds/wfds/xfds to Poller.

The Windows code still needs poll_fds[] and n_poll_fds but they can now
become local variables.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 main-loop.c | 75 ++++++++++++++++++++++++-------------------------------------
 1 file changed, 29 insertions(+), 46 deletions(-)

Patch

diff --git a/main-loop.c b/main-loop.c
index 8d552d4..c48c8f5 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -144,8 +144,6 @@  int qemu_init_main_loop(void)
 static Poller poller;
 static fd_set rfds, wfds, xfds;
 static int nfds;
-static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
-static int n_poll_fds;
 static int max_priority;
 
 /* Load rfds/wfds/xfds into Poller.  Will be removed a few commits later. */
@@ -201,34 +199,35 @@  static void poller_to_select(int ret)
 }
 
 #ifndef _WIN32
-static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
-                             fd_set *xfds, uint32_t *cur_timeout)
+static int glib_poller_idx;
+static int glib_n_poll_fds;
+
+static void glib_poller_fill(uint32_t *cur_timeout)
 {
     GMainContext *context = g_main_context_default();
-    int i;
     int timeout = 0;
+    int n, n_fds;
 
     g_main_context_prepare(context, &max_priority);
 
-    n_poll_fds = g_main_context_query(context, max_priority, &timeout,
-                                      poll_fds, ARRAY_SIZE(poll_fds));
-    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
+    n_fds = poller.max - poller.nfds;
+    while ((n = g_main_context_query(context, max_priority, &timeout,
+                                     &poller.poll_fds[poller.nfds],
+                                     n_fds)) > n_fds) {
+        poller.poll_fds = g_realloc(poller.poll_fds,
+                                    (poller.nfds + n) *
+                                    sizeof(poller.poll_fds[0]));
+        n_fds = n;
+    }
 
-    for (i = 0; i < n_poll_fds; i++) {
-        GPollFD *p = &poll_fds[i];
+    /* Stash away for later */
+    glib_poller_idx = poller.nfds;
+    glib_n_poll_fds = n;
 
-        if ((p->events & G_IO_IN)) {
-            FD_SET(p->fd, rfds);
-            *max_fd = MAX(*max_fd, p->fd);
-        }
-        if ((p->events & G_IO_OUT)) {
-            FD_SET(p->fd, wfds);
-            *max_fd = MAX(*max_fd, p->fd);
-        }
-        if ((p->events & G_IO_ERR)) {
-            FD_SET(p->fd, xfds);
-            *max_fd = MAX(*max_fd, p->fd);
-        }
+    /* Update poller book-keeping */
+    poller.nfds += n;
+    if (poller.nfds > poller.max) {
+        poller.max = poller.nfds;
     }
 
     if (timeout >= 0 && timeout < *cur_timeout) {
@@ -236,30 +235,13 @@  static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
     }
 }
 
-static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
-                             bool err)
+static void glib_poller_poll(void)
 {
     GMainContext *context = g_main_context_default();
 
-    if (!err) {
-        int i;
-
-        for (i = 0; i < n_poll_fds; i++) {
-            GPollFD *p = &poll_fds[i];
-
-            if ((p->events & G_IO_IN) && FD_ISSET(p->fd, rfds)) {
-                p->revents |= G_IO_IN;
-            }
-            if ((p->events & G_IO_OUT) && FD_ISSET(p->fd, wfds)) {
-                p->revents |= G_IO_OUT;
-            }
-            if ((p->events & G_IO_ERR) && FD_ISSET(p->fd, xfds)) {
-                p->revents |= G_IO_ERR;
-            }
-        }
-    }
-
-    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+    if (g_main_context_check(context, max_priority,
+                             &poller.poll_fds[glib_poller_idx],
+                             glib_n_poll_fds)) {
         g_main_context_dispatch(context);
     }
 }
@@ -268,7 +250,7 @@  static int os_host_main_loop_wait(uint32_t timeout)
 {
     int ret;
 
-    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
+    glib_poller_fill(&timeout);
 
     if (timeout > 0) {
         qemu_mutex_unlock_iothread();
@@ -287,7 +269,7 @@  static int os_host_main_loop_wait(uint32_t timeout)
         qemu_mutex_lock_iothread();
     }
 
-    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    glib_poller_poll();
     return ret;
 }
 #else
@@ -384,8 +366,9 @@  void qemu_fd_register(int fd)
 static int os_host_main_loop_wait(uint32_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;
+    int g_poll_ret, ret, i, n_poll_fds;
     PollingEntry *pe;
     WaitObjects *w = &wait_objects;
     gint poll_timeout;