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 <pingf...@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