* [Qemu-devel] [PATCH 0/2] make slirp drivern by glib directly
@ 2013-10-28 1:16 Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 1/2] slirp: introduce gsource event abstraction Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 2/2] slirp: make slirp event dispatch based on slirp instance Liu Ping Fan
0 siblings, 2 replies; 3+ messages in thread
From: Liu Ping Fan @ 2013-10-28 1:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi, Jan Kiszka
This series make slirp drivern directly by glib, so we can clean up
the hooks for slrip in mainloop and stub
Liu Ping Fan (2):
slirp: introduce gsource event abstraction
slirp: make slirp event dispatch based on slirp instance
main-loop.c | 6 ---
net/slirp.c | 3 ++
slirp/Makefile.objs | 2 +-
slirp/TFX7d70.tmp | 0
slirp/libslirp.h | 7 ++-
slirp/slirp.c | 133 ++++++++++++++++----------------------------------
slirp/slirp.h | 1 +
slirp/slirp_gsource.c | 94 +++++++++++++++++++++++++++++++++++
slirp/slirp_gsource.h | 37 ++++++++++++++
slirp/socket.c | 1 -
slirp/socket.h | 2 +-
stubs/Makefile.objs | 1 -
stubs/slirp.c | 11 -----
13 files changed, 181 insertions(+), 117 deletions(-)
create mode 100644 slirp/TFX7d70.tmp
create mode 100644 slirp/slirp_gsource.c
create mode 100644 slirp/slirp_gsource.h
delete mode 100644 stubs/slirp.c
--
1.8.1.4
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 1/2] slirp: introduce gsource event abstraction
2013-10-28 1:16 [Qemu-devel] [PATCH 0/2] make slirp drivern by glib directly Liu Ping Fan
@ 2013-10-28 1:16 ` Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 2/2] slirp: make slirp event dispatch based on slirp instance Liu Ping Fan
1 sibling, 0 replies; 3+ messages in thread
From: Liu Ping Fan @ 2013-10-28 1:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi, Jan Kiszka
Introduce struct SlirpGSource. It will ease the usage of GSource
associated with a group of files, which are dynamically allocated
and release for slirp.
Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
slirp/Makefile.objs | 2 +-
slirp/slirp_gsource.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++
slirp/slirp_gsource.h | 37 ++++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 slirp/slirp_gsource.c
create mode 100644 slirp/slirp_gsource.h
diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 2daa9dc..ee39eed 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -1,3 +1,3 @@
common-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o dnssearch.o
-common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
+common-obj-y += slirp.o slirp_gsource.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
common-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
diff --git a/slirp/slirp_gsource.c b/slirp/slirp_gsource.c
new file mode 100644
index 0000000..b502697
--- /dev/null
+++ b/slirp/slirp_gsource.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2013 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "slirp_gsource.h"
+#include "qemu/bitops.h"
+
+GPollFD *slirp_gsource_add_pollfd(SlirpGSource *src, int fd)
+{
+ GPollFD *retfd;
+
+ retfd = g_slice_alloc(sizeof(GPollFD));
+ retfd->events = 0;
+ retfd->fd = fd;
+ src->pollfds_list = g_list_append(src->pollfds_list, retfd);
+ if (fd >= 0) {
+ g_source_add_poll(&src->source, retfd);
+ }
+
+ return retfd;
+}
+
+void slirp_gsource_remove_pollfd(SlirpGSource *src, GPollFD *pollfd)
+{
+ g_source_remove_poll(&src->source, pollfd);
+ src->pollfds_list = g_list_remove(src->pollfds_list, pollfd);
+ g_slice_free(GPollFD, pollfd);
+}
+
+static gboolean slirp_gsource_check(GSource *src)
+{
+ SlirpGSource *nsrc = (SlirpGSource *)src;
+ GList *cur;
+ GPollFD *gfd;
+
+ cur = nsrc->pollfds_list;
+ while (cur) {
+ gfd = cur->data;
+ if (gfd->fd >= 0 && (gfd->revents & gfd->events)) {
+ return true;
+ }
+ cur = g_list_next(cur);
+ }
+
+ return false;
+}
+
+static gboolean slirp_gsource_dispatch(GSource *src, GSourceFunc cb,
+ gpointer data)
+{
+ gboolean ret = false;
+
+ if (cb) {
+ ret = cb(data);
+ }
+ return ret;
+}
+
+SlirpGSource *slirp_gsource_new(GPrepare prepare, GSourceFunc dispatch_cb,
+ void *opaque)
+{
+ SlirpGSource *src;
+ GSourceFuncs *gfuncs = g_new0(GSourceFuncs, 1);
+ gfuncs->prepare = prepare;
+ gfuncs->check = slirp_gsource_check,
+ gfuncs->dispatch = slirp_gsource_dispatch,
+
+ src = (SlirpGSource *)g_source_new(gfuncs, sizeof(SlirpGSource));
+ src->gfuncs = gfuncs;
+ src->pollfds_list = NULL;
+ src->opaque = opaque;
+ g_source_set_callback(&src->source, dispatch_cb, src, NULL);
+
+ return src;
+}
+
+void slirp_gsource_release(SlirpGSource *src)
+{
+ assert(!src->pollfds_list);
+ g_free(src->gfuncs);
+ g_source_destroy(&src->source);
+}
diff --git a/slirp/slirp_gsource.h b/slirp/slirp_gsource.h
new file mode 100644
index 0000000..98a9e3a
--- /dev/null
+++ b/slirp/slirp_gsource.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SLIRP_GSOURCE_H
+#define SLIRP_GSOURCE_H
+#include "qemu-common.h"
+
+typedef gboolean (*GPrepare)(GSource *source, gint *timeout_);
+
+/* multi fd drive GSource*/
+typedef struct SlirpGSource {
+ GSource source;
+ /* a group of GPollFD which dynamically join or leave the GSource */
+ GList *pollfds_list;
+ GSourceFuncs *gfuncs;
+ void *opaque;
+} SlirpGSource;
+
+SlirpGSource *slirp_gsource_new(GPrepare prepare, GSourceFunc dispatch_cb,
+ void *opaque);
+void slirp_gsource_release(SlirpGSource *src);
+GPollFD *slirp_gsource_add_pollfd(SlirpGSource *src, int fd);
+void slirp_gsource_remove_pollfd(SlirpGSource *src, GPollFD *pollfd);
+#endif
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 2/2] slirp: make slirp event dispatch based on slirp instance
2013-10-28 1:16 [Qemu-devel] [PATCH 0/2] make slirp drivern by glib directly Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 1/2] slirp: introduce gsource event abstraction Liu Ping Fan
@ 2013-10-28 1:16 ` Liu Ping Fan
1 sibling, 0 replies; 3+ messages in thread
From: Liu Ping Fan @ 2013-10-28 1:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Stefan Hajnoczi, Jan Kiszka
Each slirp instance has its own GFuncs, so we can driver slirp by glib main loop.
Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
For easing the review, This patch does not obey coding guide. Will fix
it later
---
main-loop.c | 6 ---
net/slirp.c | 3 ++
slirp/TFX7d70.tmp | 0
slirp/libslirp.h | 7 ++-
slirp/slirp.c | 133 ++++++++++++++++------------------------------------
slirp/slirp.h | 1 +
slirp/socket.c | 1 -
slirp/socket.h | 2 +-
stubs/Makefile.objs | 1 -
stubs/slirp.c | 11 -----
10 files changed, 49 insertions(+), 116 deletions(-)
create mode 100644 slirp/TFX7d70.tmp
delete mode 100644 stubs/slirp.c
diff --git a/main-loop.c b/main-loop.c
index c3c9c28..374d26f 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -465,9 +465,6 @@ int main_loop_wait(int nonblocking)
/* poll any events */
g_array_set_size(gpollfds, 0); /* reset for new iteration */
/* XXX: separate device handlers from system ones */
-#ifdef CONFIG_SLIRP
- slirp_pollfds_fill(gpollfds, &timeout);
-#endif
qemu_iohandler_fill(gpollfds);
if (timeout == UINT32_MAX) {
@@ -482,9 +479,6 @@ int main_loop_wait(int nonblocking)
ret = os_host_main_loop_wait(timeout_ns);
qemu_iohandler_poll(gpollfds, ret);
-#ifdef CONFIG_SLIRP
- slirp_pollfds_poll(gpollfds, (ret < 0));
-#endif
qemu_clock_run_all_timers();
diff --git a/net/slirp.c b/net/slirp.c
index 124e953..2a21e16 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -35,6 +35,7 @@
#include "monitor/monitor.h"
#include "qemu/sockets.h"
#include "slirp/libslirp.h"
+#include "slirp/slirp_gsource.h"
#include "sysemu/char.h"
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
@@ -76,6 +77,7 @@ typedef struct SlirpState {
#ifndef _WIN32
char smb_dir[128];
#endif
+ SlirpGSource *slirp_src;
} SlirpState;
static struct slirp_config_str *slirp_configs;
@@ -244,6 +246,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
s->slirp = slirp_init(restricted, net, mask, host, vhostname,
tftp_export, bootfile, dhcp, dns, dnssearch, s);
+ s->slirp_src = slirp_gsource_new(slirp_prepare, slirp_handler, s->slirp);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
for (config = slirp_configs; config; config = config->next) {
diff --git a/slirp/TFX7d70.tmp b/slirp/TFX7d70.tmp
new file mode 100644
index 0000000..e69de29
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 5bdcbd5..bb0c537 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -16,10 +16,6 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
void *opaque);
void slirp_cleanup(Slirp *slirp);
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
-
-void slirp_pollfds_poll(GArray *pollfds, int select_error);
-
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
/* you must provide the following functions: */
@@ -39,5 +35,8 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
int guest_port, const uint8_t *buf, int size);
size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr,
int guest_port);
+gboolean slirp_prepare(GSource *source, gint *time);
+gboolean slirp_handler(gpointer data);
+
#endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index bad8dad..6d57994 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -25,6 +25,7 @@
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "slirp.h"
+#include "slirp_gsource.h"
#include "hw/hw.h"
/* host loopback address */
@@ -262,46 +263,34 @@ void slirp_cleanup(Slirp *slirp)
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-static void slirp_update_timeout(uint32_t *timeout)
+static void slirp_update_timeout(Slirp *slirp, gint *timeout)
{
- Slirp *slirp;
- uint32_t t;
+ gint t = *timeout;
if (*timeout <= TIMEOUT_FAST) {
return;
}
- t = MIN(1000, *timeout);
-
- /* If we have tcp timeout with slirp, then we will fill @timeout with
- * more precise value.
- */
- QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
- if (slirp->time_fasttimo) {
- *timeout = TIMEOUT_FAST;
- return;
- }
- if (slirp->do_slowtimo) {
- t = MIN(TIMEOUT_SLOW, t);
- }
+ if (slirp->time_fasttimo) {
+ *timeout = TIMEOUT_FAST;
+ return;
+ }
+ if (slirp->do_slowtimo) {
+ t = MIN(TIMEOUT_SLOW, t);
}
*timeout = t;
}
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
+gboolean slirp_prepare(GSource *source, gint *time)
{
- Slirp *slirp;
+ SlirpGSource *slirp_src = (SlirpGSource *)source;
+ Slirp *slirp = slirp_src->opaque;
struct socket *so, *so_next;
+ u_int curtime;
- if (QTAILQ_EMPTY(&slirp_instances)) {
- return;
- }
-
- /*
- * First, TCP sockets
- */
+ curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ slirp->curtime = curtime;
- QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
* *_slowtimo needs calling if there are IP fragments
* in the fragment queue, or there are TCP connections active
@@ -315,7 +304,10 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
so_next = so->so_next;
- so->pollfds_idx = -1;
+ if (so->pollfd->fd == -1 && so->s != -1) {
+ so->pollfd->fd = so->s;
+ g_source_add_poll(source, so->pollfd);
+ }
/*
* See if we need a tcp_fasttimo
@@ -337,12 +329,7 @@ void slirp_pollfds_fill(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->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
continue;
}
@@ -350,12 +337,7 @@ void slirp_pollfds_fill(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->pollfd->events = G_IO_OUT | G_IO_ERR;
continue;
}
@@ -377,12 +359,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
}
if (events) {
- GPollFD pfd = {
- .fd = so->s,
- .events = events,
- };
- so->pollfds_idx = pollfds->len;
- g_array_append_val(pollfds, pfd);
+ so->pollfd->events = events;
}
}
@@ -393,8 +370,6 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
so = so_next) {
so_next = so->so_next;
- so->pollfds_idx = -1;
-
/*
* See if it's timed out
*/
@@ -418,12 +393,7 @@ void slirp_pollfds_fill(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->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
}
}
@@ -434,8 +404,6 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
so = so_next) {
so_next = so->so_next;
- so->pollfds_idx = -1;
-
/*
* See if it's timed out
*/
@@ -449,31 +417,22 @@ void slirp_pollfds_fill(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->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
}
}
- }
- slirp_update_timeout(timeout);
+
+ slirp_update_timeout(slirp, time);
+ return false;
}
-void slirp_pollfds_poll(GArray *pollfds, int select_error)
+gboolean slirp_handler(gpointer data)
{
- Slirp *slirp;
+ SlirpGSource *src = data;
+ Slirp *slirp = src->opaque;
struct socket *so, *so_next;
int ret;
+ u_int curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
- if (QTAILQ_EMPTY(&slirp_instances)) {
- return;
- }
-
- curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
-
- QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
* See if anything has timed out
*/
@@ -489,23 +448,17 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
slirp->last_slowtimo = curtime;
}
- /*
- * Check sockets
- */
- if (!select_error) {
/*
* Check TCP sockets
*/
for (so = slirp->tcb.so_next; so != &slirp->tcb;
so = so_next) {
- int revents;
+ int revents = 0;
so_next = so->so_next;
- revents = 0;
- if (so->pollfds_idx != -1) {
- revents = g_array_index(pollfds, GPollFD,
- so->pollfds_idx).revents;
+ if (so->pollfd) {
+ revents = so->pollfd->revents;
}
if (so->so_state & SS_NOFDREF || so->s == -1) {
@@ -629,14 +582,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
*/
for (so = slirp->udb.so_next; so != &slirp->udb;
so = so_next) {
- int revents;
+ int revents = 0;
so_next = so->so_next;
- revents = 0;
- if (so->pollfds_idx != -1) {
- revents = g_array_index(pollfds, GPollFD,
- so->pollfds_idx).revents;
+ if (so->pollfd) {
+ revents = so->pollfd->revents;
}
if (so->s != -1 &&
@@ -650,14 +601,13 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
*/
for (so = slirp->icmp.so_next; so != &slirp->icmp;
so = so_next) {
- int revents;
+ int revents = 0;
so_next = so->so_next;
revents = 0;
- if (so->pollfds_idx != -1) {
- revents = g_array_index(pollfds, GPollFD,
- so->pollfds_idx).revents;
+ if (so->pollfd) {
+ revents = so->pollfd->revents;
}
if (so->s != -1 &&
@@ -665,10 +615,9 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
icmp_receive(so);
}
}
- }
if_start(slirp);
- }
+ return true;
}
static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
diff --git a/slirp/slirp.h b/slirp/slirp.h
index e4a1bd4..ea08b4d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -206,6 +206,7 @@ struct Slirp {
u_int time_fasttimo;
u_int last_slowtimo;
bool do_slowtimo;
+ u_int curtime;
/* virtual network configuration */
struct in_addr vnetwork_addr;
diff --git a/slirp/socket.c b/slirp/socket.c
index 37ac5cf..8b130e8 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -51,7 +51,6 @@ socreate(Slirp *slirp)
so->so_state = SS_NOFDREF;
so->s = -1;
so->slirp = slirp;
- so->pollfds_idx = -1;
}
return(so);
}
diff --git a/slirp/socket.h b/slirp/socket.h
index 57e0407..373601f 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -20,7 +20,7 @@ struct socket {
int s; /* The actual socket */
- int pollfds_idx; /* GPollFD GArray index */
+ GPollFD *pollfd;
Slirp *slirp; /* managing slirp instance */
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index df92fe5..130be9f 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -20,7 +20,6 @@ stub-obj-y += mon-set-error.o
stub-obj-y += pci-drive-hot-add.o
stub-obj-y += reset.o
stub-obj-y += set-fd-handler.o
-stub-obj-y += slirp.o
stub-obj-y += sysbus.o
stub-obj-y += uuid.o
stub-obj-y += vm-stop.o
diff --git a/stubs/slirp.c b/stubs/slirp.c
deleted file mode 100644
index bd0ac7f..0000000
--- a/stubs/slirp.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "qemu-common.h"
-#include "slirp/slirp.h"
-
-void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
-{
-}
-
-void slirp_pollfds_poll(GArray *pollfds, int select_error)
-{
-}
-
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-10-28 1:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-28 1:16 [Qemu-devel] [PATCH 0/2] make slirp drivern by glib directly Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 1/2] slirp: introduce gsource event abstraction Liu Ping Fan
2013-10-28 1:16 ` [Qemu-devel] [PATCH 2/2] slirp: make slirp event dispatch based on slirp instance Liu Ping Fan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).