@@ -8,3 +8,4 @@ util-obj-y += error.o qemu-error.o
util-obj-$(CONFIG_POSIX) += compatfd.o
util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o
util-obj-y += qemu-option.o qemu-progress.o
+util-obj-y += event_gsource.o
new file mode 100644
@@ -0,0 +1,158 @@
+/*
+ * 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 "event_gsource.h"
+#include "qemu/bitops.h"
+
+static gboolean prepare(GSource *src, gint *time)
+{
+ EventGSource *nsrc = (EventGSource *)src;
+ int events = 0;
+
+ if (!nsrc->readable && !nsrc->writable) {
+ return false;
+ }
+ if (nsrc->readable) {
+ events = nsrc->readable(nsrc->opaque);
+ }
+ if ((nsrc->writable)) {
+ events |= nsrc->writable(nsrc->opaque);
+ }
+ nsrc->gfd.events = events;
+
+ return false;
+}
+
+static gboolean check(GSource *src)
+{
+ EventGSource *nsrc = (EventGSource *)src;
+
+ if (nsrc->gfd.revents & nsrc->gfd.events) {
+ return true;
+ }
+ return false;
+}
+
+static gboolean dispatch(GSource *src, GSourceFunc cb, gpointer data)
+{
+ gboolean ret = false;
+
+ if (cb) {
+ ret = cb(data);
+ }
+ return ret;
+}
+
+static GSourceFuncs net_gsource_funcs = {
+ prepare,
+ check,
+ dispatch,
+ NULL
+};
+
+EventGSource *event_source_new(int fd, GSourceFunc dispatch_cb, void *opaque)
+{
+ EventGSource *nsrc = (EventGSource *)g_source_new(&net_gsource_funcs,
+ sizeof(EventGSource));
+ nsrc->gfd.fd = fd;
+ nsrc->opaque = opaque;
+ g_source_set_callback(&nsrc->source, dispatch_cb, nsrc, NULL);
+ g_source_add_poll(&nsrc->source, &nsrc->gfd);
+
+ return nsrc;
+}
+
+void event_source_release(EventGSource *src)
+{
+ g_source_destroy(&src->source);
+}
+
+GPollFD *events_source_add_gfd(EventsGSource *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 events_source_remove_gfd(EventsGSource *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 events_source_check(GSource *src)
+{
+ EventsGSource *nsrc = (EventsGSource *)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 events_source_dispatch(GSource *src, GSourceFunc cb,
+ gpointer data)
+{
+ gboolean ret = false;
+
+ if (cb) {
+ ret = cb(data);
+ }
+ return ret;
+}
+
+EventsGSource *events_source_new(GPrepare prepare, GSourceFunc dispatch_cb,
+ void *opaque)
+{
+ EventsGSource *src;
+ GSourceFuncs *gfuncs = g_new0(GSourceFuncs, 1);
+ gfuncs->prepare = prepare;
+ gfuncs->check = events_source_check,
+ gfuncs->dispatch = events_source_dispatch,
+
+ src = (EventsGSource *)g_source_new(gfuncs, sizeof(EventsGSource));
+ src->gfuncs = gfuncs;
+ src->pollfds_list = NULL;
+ src->opaque = opaque;
+ g_source_set_callback(&src->source, dispatch_cb, src, NULL);
+
+ return src;
+}
+
+void events_source_release(EventsGSource *src)
+{
+ g_list_free(src->pollfds_list);
+ g_free(src->gfuncs);
+ g_source_destroy(&src->source);
+}
+
new file mode 100644
@@ -0,0 +1,49 @@
+/*
+ * 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 EVENT_GSOURCE_H
+#define EVENT_GSOURCE_H
+#include "qemu-common.h"
+
+typedef gushort (*Pollable)(void *opaque);
+typedef gboolean (*GPrepare)(GSource *source, gint *timeout_);
+
+/* single fd drive gsource */
+typedef struct EventGSource {
+ GSource source;
+ GPollFD gfd;
+ Pollable readable;
+ Pollable writable;
+ void *opaque;
+} EventGSource;
+
+EventGSource *event_source_new(int fd, GSourceFunc dispatch_cb, void *opaque);
+void event_source_release(EventGSource *src);
+
+/* multi fd drive gsource*/
+typedef struct EventsGSource {
+ GSource source;
+ GList *pollfds_list;
+ GSourceFuncs *gfuncs;
+ void *opaque;
+} EventsGSource;
+
+EventsGSource *events_source_new(GPrepare prepare, GSourceFunc dispatch_cb,
+ void *opaque);
+void events_source_release(EventsGSource *src);
+GPollFD *events_source_add_gfd(EventsGSource *src, int fd);
+void events_source_remove_gfd(EventsGSource *src, GPollFD *pollfd);
+#endif