diff mbox series

[PULLv3,30/32] slirp: use polling callbacks, drop glib requirement

Message ID 20190205182848.29887-31-samuel.thibault@ens-lyon.org (mailing list archive)
State New, archived
Headers show
Series [PULLv3,01/32] slirp: Avoid unaligned 16bit memory access | expand

Commit Message

Samuel Thibault Feb. 5, 2019, 6:28 p.m. UTC
From: Marc-André Lureau <marcandre.lureau@redhat.com>

It would be legitimate to use libslirp without glib. Let's
add_poll/get_revents pair of callbacks to provide the same
functionality.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 net/slirp.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
 slirp/libslirp.h | 17 ++++++++++--
 slirp/slirp.c    | 72 +++++++++++++++++-------------------------------
 3 files changed, 109 insertions(+), 52 deletions(-)
diff mbox series

Patch

diff --git a/net/slirp.c b/net/slirp.c
index 4d55f64168..a85e42ff43 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -211,6 +211,71 @@  static const SlirpCb slirp_cb = {
     .notify = qemu_notify_event,
 };
 
+static int slirp_poll_to_gio(int events)
+{
+    int ret = 0;
+
+    if (events & SLIRP_POLL_IN) {
+        ret |= G_IO_IN;
+    }
+    if (events & SLIRP_POLL_OUT) {
+        ret |= G_IO_OUT;
+    }
+    if (events & SLIRP_POLL_PRI) {
+        ret |= G_IO_PRI;
+    }
+    if (events & SLIRP_POLL_ERR) {
+        ret |= G_IO_ERR;
+    }
+    if (events & SLIRP_POLL_HUP) {
+        ret |= G_IO_HUP;
+    }
+
+    return ret;
+}
+
+static int net_slirp_add_poll(int fd, int events, void *opaque)
+{
+    GArray *pollfds = opaque;
+    GPollFD pfd = {
+        .fd = fd,
+        .events = slirp_poll_to_gio(events),
+    };
+    int idx = pollfds->len;
+    g_array_append_val(pollfds, pfd);
+    return idx;
+}
+
+static int slirp_gio_to_poll(int events)
+{
+    int ret = 0;
+
+    if (events & G_IO_IN) {
+        ret |= SLIRP_POLL_IN;
+    }
+    if (events & G_IO_OUT) {
+        ret |= SLIRP_POLL_OUT;
+    }
+    if (events & G_IO_PRI) {
+        ret |= SLIRP_POLL_PRI;
+    }
+    if (events & G_IO_ERR) {
+        ret |= SLIRP_POLL_ERR;
+    }
+    if (events & G_IO_HUP) {
+        ret |= SLIRP_POLL_HUP;
+    }
+
+    return ret;
+}
+
+static int net_slirp_get_revents(int idx, void *opaque)
+{
+    GArray *pollfds = opaque;
+
+    return slirp_gio_to_poll(g_array_index(pollfds, GPollFD, idx).revents);
+}
+
 static void net_slirp_poll_notify(Notifier *notifier, void *data)
 {
     MainLoopPoll *poll = data;
@@ -218,12 +283,13 @@  static void net_slirp_poll_notify(Notifier *notifier, void *data)
 
     switch (poll->state) {
     case MAIN_LOOP_POLL_FILL:
-        slirp_pollfds_fill(s->slirp, poll->pollfds, &poll->timeout);
+        slirp_pollfds_fill(s->slirp, &poll->timeout,
+                           net_slirp_add_poll, poll->pollfds);
         break;
     case MAIN_LOOP_POLL_OK:
     case MAIN_LOOP_POLL_ERR:
-        slirp_pollfds_poll(s->slirp, poll->pollfds,
-                           poll->state == MAIN_LOOP_POLL_ERR);
+        slirp_pollfds_poll(s->slirp, poll->state == MAIN_LOOP_POLL_ERR,
+                           net_slirp_get_revents, poll->pollfds);
         break;
     default:
         g_assert_not_reached();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18d5fb0133..b5c1b2122b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -1,7 +1,6 @@ 
 #ifndef LIBSLIRP_H
 #define LIBSLIRP_H
 
-#include <glib.h>
 #include <stdint.h>
 #include <stdbool.h>
 
@@ -15,8 +14,18 @@ 
 
 typedef struct Slirp Slirp;
 
+enum {
+    SLIRP_POLL_IN  = 1 << 0,
+    SLIRP_POLL_OUT = 1 << 1,
+    SLIRP_POLL_PRI = 1 << 2,
+    SLIRP_POLL_ERR = 1 << 3,
+    SLIRP_POLL_HUP = 1 << 4,
+};
+
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
+typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
 
 /*
  * Callbacks from slirp
@@ -63,9 +72,11 @@  Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
                   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout);
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+                        SlirpAddPollCb add_poll, void *opaque);
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error);
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+                        SlirpGetREventsCb get_revents, void *opaque);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ecbb5c5b6c..04886d05fd 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -386,7 +386,8 @@  static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout)
     *timeout = t;
 }
 
-void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
+void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
+                        SlirpAddPollCb add_poll, void *opaque)
 {
     struct socket *so, *so_next;
 
@@ -428,12 +429,8 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * Set for reading sockets which are accepting
          */
         if (so->so_state & SS_FACCEPTCONN) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
             continue;
         }
 
@@ -441,12 +438,8 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * Set for writing sockets which are connecting
          */
         if (so->so_state & SS_ISFCONNECTING) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_OUT | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_OUT | SLIRP_POLL_ERR, opaque);
             continue;
         }
 
@@ -455,7 +448,7 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * we have something to send
          */
         if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
-            events |= G_IO_OUT | G_IO_ERR;
+            events |= SLIRP_POLL_OUT | SLIRP_POLL_ERR;
         }
 
         /*
@@ -464,16 +457,12 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          */
         if (CONN_CANFRCV(so) &&
             (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
-            events |= G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI;
+            events |= SLIRP_POLL_IN | SLIRP_POLL_HUP |
+                      SLIRP_POLL_ERR | SLIRP_POLL_PRI;
         }
 
         if (events) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = events,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s, events, opaque);
         }
     }
 
@@ -508,12 +497,8 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
          * (XXX <= 4 ?)
          */
         if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
         }
     }
 
@@ -538,19 +523,16 @@  void slirp_pollfds_fill(Slirp *slirp, GArray *pollfds, uint32_t *timeout)
         }
 
         if (so->so_state & SS_ISFCONNECTED) {
-            GPollFD pfd = {
-                .fd = so->s,
-                .events = G_IO_IN | G_IO_HUP | G_IO_ERR,
-            };
-            so->pollfds_idx = pollfds->len;
-            g_array_append_val(pollfds, pfd);
+            so->pollfds_idx = add_poll(so->s,
+                SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque);
         }
     }
 
     slirp_update_timeout(slirp, timeout);
 }
 
-void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
+void slirp_pollfds_poll(Slirp *slirp, int select_error,
+                        SlirpGetREventsCb get_revents, void *opaque)
 {
     struct socket *so, *so_next;
     int ret;
@@ -587,8 +569,7 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->so_state & SS_NOFDREF || so->s == -1) {
@@ -598,9 +579,9 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
             /*
              * Check for URG data
              * This will soread as well, so no need to
-             * test for G_IO_IN below if this succeeds
+             * test for SLIRP_POLL_IN below if this succeeds
              */
-            if (revents & G_IO_PRI) {
+            if (revents & SLIRP_POLL_PRI) {
                 ret = sorecvoob(so);
                 if (ret < 0) {
                     /* Socket error might have resulted in the socket being
@@ -611,7 +592,8 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
             /*
              * Check sockets for reading
              */
-            else if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+            else if (revents &
+                     (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR)) {
                 /*
                  * Check for incoming connections
                  */
@@ -636,7 +618,7 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
              * Check sockets for writing
              */
             if (!(so->so_state & SS_NOFDREF) &&
-                (revents & (G_IO_OUT | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_OUT | SLIRP_POLL_ERR))) {
                 /*
                  * Check for non-blocking, still-connecting sockets
                  */
@@ -689,12 +671,11 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->s != -1 &&
-                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
                 sorecvfrom(so);
             }
         }
@@ -710,12 +691,11 @@  void slirp_pollfds_poll(Slirp *slirp, GArray *pollfds, int select_error)
 
             revents = 0;
             if (so->pollfds_idx != -1) {
-                revents = g_array_index(pollfds, GPollFD,
-                                        so->pollfds_idx).revents;
+                revents = get_revents(so->pollfds_idx, opaque);
             }
 
             if (so->s != -1 &&
-                (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
+                (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
                 icmp_receive(so);
             }
         }