qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Liu Ping Fan <qemulist@gmail.com>
To: qemu-devel@nongnu.org
Cc: mdroth <mdroth@linux.vnet.ibm.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Anthony Liguori <anthony@codemonkey.ws>,
	Jan Kiszka <jan.kiszka@siemens.com>
Subject: [Qemu-devel] [RFC PATCH v4 01/15] util: introduce gsource event abstration
Date: Wed, 17 Apr 2013 16:39:10 +0800	[thread overview]
Message-ID: <1366187964-14265-2-git-send-email-qemulist@gmail.com> (raw)
In-Reply-To: <1366187964-14265-1-git-send-email-qemulist@gmail.com>

From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>

Introduce two structs EventGSource, EventsGSource
EventGSource is used to abstract the event with single backend file.
EventsGSource is used to abstract the event with dynamicly changed
backend file, ex, slirp.

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
 util/Makefile.objs   |    1 +
 util/event_gsource.c |  169 ++++++++++++++++++++++++++++++++++++++++++++++++++
 util/event_gsource.h |   54 ++++++++++++++++
 3 files changed, 224 insertions(+), 0 deletions(-)
 create mode 100644 util/event_gsource.c
 create mode 100644 util/event_gsource.h

diff --git a/util/Makefile.objs b/util/Makefile.objs
index 495a178..a676d7d 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -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
diff --git a/util/event_gsource.c b/util/event_gsource.c
new file mode 100644
index 0000000..b255c47
--- /dev/null
+++ b/util/event_gsource.c
@@ -0,0 +1,169 @@
+/*
+ *  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 && nsrc->readable(nsrc->opaque)) {
+        events |= G_IO_IN;
+    }
+    if ((nsrc->writable) && nsrc->writable(nsrc->opaque)) {
+        events |= G_IO_OUT;
+    }
+    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_get_gfd(EventsGSource *src, int fd)
+{
+    GPollFD *retfd;
+    unsigned long idx;
+
+    idx = find_first_zero_bit(src->alloc_bmp, src->bmp_sz);
+    if (idx == src->bmp_sz) {
+        //idx = src->bmp_sz;
+        src->bmp_sz += 8;
+        src->alloc_bmp = g_realloc(src->alloc_bmp, src->bmp_sz >> 3);
+        src->pollfds = g_realloc(src->pollfds, src->bmp_sz);
+    }
+    set_bit(idx, src->alloc_bmp);
+
+    retfd = src->pollfds + idx;
+    retfd->events = 0;
+    retfd->fd = fd;
+    if (fd > 0) {
+        g_source_add_poll(&src->source, retfd);
+    }
+
+    return retfd;
+}
+
+void events_source_close_gfd(EventsGSource *src, GPollFD *pollfd)
+{
+    unsigned long idx;
+
+    idx = pollfd - src->pollfds;
+    clear_bit(idx, src->alloc_bmp);
+    g_source_remove_poll(&src->source, pollfd);
+}
+
+gboolean events_source_check(GSource *src)
+{
+    unsigned long idx = 0;
+    EventsGSource *nsrc = (EventsGSource *)src;
+    unsigned long sz = nsrc->bmp_sz;
+    GPollFD *gfd;
+
+    do {
+        idx = find_next_bit(nsrc->alloc_bmp, sz, idx);
+        if (idx < sz) {
+            gfd = nsrc->pollfds + idx;
+            if (gfd->revents & gfd->events) {
+                return true;
+            }
+            idx++;
+            continue;
+        } else {
+            return false;
+        }
+    } while (true);
+}
+
+gboolean events_source_dispatch(GSource *src, GSourceFunc cb, gpointer data)
+{
+    gboolean ret = false;
+
+    if (cb) {
+        ret = cb(data);
+    }
+    return ret;
+}
+
+EventsGSource *events_source_new(GSourceFuncs *funcs, GSourceFunc dispatch_cb, void *opaque)
+{
+    EventsGSource *src = (EventsGSource *)g_source_new(funcs, sizeof(EventsGSource));
+
+    /* 8bits size at initial */
+    src->bmp_sz = 8;
+    src->alloc_bmp = g_malloc0(src->bmp_sz >> 3);
+    src->pollfds = g_malloc0(8 * sizeof(GPollFD));
+    src->opaque = opaque;
+    g_source_set_callback(&src->source, dispatch_cb, src, NULL);
+
+    return src;
+}
+
+void events_source_release(EventsGSource *src)
+{
+    g_free(src->alloc_bmp);
+    g_free(src->pollfds);
+    g_source_destroy(&src->source);
+    g_free(src);
+}
+
diff --git a/util/event_gsource.h b/util/event_gsource.h
new file mode 100644
index 0000000..fd07e6d
--- /dev/null
+++ b/util/event_gsource.h
@@ -0,0 +1,54 @@
+/*
+ *  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 bool (*Pollable)(void *opaque);
+
+/* 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;
+    /* 8 for initial, stand for 8 pollfds */
+    unsigned int bmp_sz;
+    unsigned long *alloc_bmp;
+    GPollFD *pollfds;
+    void *opaque;
+} EventsGSource;
+
+EventsGSource *events_source_new(GSourceFuncs *funcs, GSourceFunc dispatch_cb, void *opaque);
+void events_source_release(EventsGSource *src);
+gboolean events_source_check(GSource *src);
+gboolean events_source_dispatch(GSource *src, GSourceFunc cb, gpointer data);
+GPollFD *events_source_get_gfd(EventsGSource *src, int fd);
+void events_source_close_gfd(EventsGSource *src, GPollFD *pollfd);
+
+
+
+#endif
-- 
1.7.4.4

  reply	other threads:[~2013-04-17  8:39 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-17  8:39 [Qemu-devel] [RFC PATCH v4 00/15] port network layer onto glib Liu Ping Fan
2013-04-17  8:39 ` Liu Ping Fan [this message]
2013-04-18 14:01   ` [Qemu-devel] [RFC PATCH v4 01/15] util: introduce gsource event abstration Stefan Hajnoczi
2013-04-19  6:52     ` liu ping fan
2013-04-19 11:59       ` Stefan Hajnoczi
2013-04-22  7:50         ` liu ping fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 02/15] net: introduce bind_ctx to NetClientInfo Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 03/15] net: port tap onto GSource Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 04/15] net: resolve race of tap backend and its peer Liu Ping Fan
2013-04-18 14:11   ` Stefan Hajnoczi
2013-04-19  5:43     ` liu ping fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 05/15] net: port vde onto GSource Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 06/15] net: port socket to GSource Liu Ping Fan
2013-04-18 14:34   ` Stefan Hajnoczi
2013-04-19  5:58     ` liu ping fan
2013-04-19 12:03       ` Stefan Hajnoczi
2013-04-22  7:52         ` liu ping fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 07/15] net: port tap-win32 onto GSource Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 08/15] net: hub use lock to protect ports list Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 09/15] net: introduce lock to protect NetQueue Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 10/15] net: introduce lock to protect NetClientState's peer's access Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 11/15] net: make netclient re-entrant with refcnt Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 12/15] slirp: make timeout local Liu Ping Fan
2013-04-18 14:22   ` Paolo Bonzini
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 13/15] slirp: make slirp event dispatch based on slirp instance, not global Liu Ping Fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 14/15] slirp: handle race condition Liu Ping Fan
2013-04-18  7:13   ` Jan Kiszka
2013-04-19  0:18     ` liu ping fan
2013-04-19  8:21       ` Jan Kiszka
2013-04-22  5:55         ` liu ping fan
2013-04-23  7:20           ` liu ping fan
2013-04-17  8:39 ` [Qemu-devel] [RFC PATCH v4 15/15] slirp: use lock to protect the slirp_instances Liu Ping Fan
2013-04-18  7:20   ` Jan Kiszka
2013-04-18 14:16     ` Paolo Bonzini
2013-04-19  6:13       ` liu ping fan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1366187964-14265-2-git-send-email-qemulist@gmail.com \
    --to=qemulist@gmail.com \
    --cc=anthony@codemonkey.ws \
    --cc=jan.kiszka@siemens.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).