From patchwork Fri Apr 26 02:47:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 239625 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 94D142C00DA for ; Fri, 26 Apr 2013 12:48:27 +1000 (EST) Received: from localhost ([::1]:41979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVYi1-0001RX-TU for incoming@patchwork.ozlabs.org; Thu, 25 Apr 2013 22:48:25 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49166) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVYhf-0001M1-Ga for qemu-devel@nongnu.org; Thu, 25 Apr 2013 22:48:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UVYhd-0007fc-Qp for qemu-devel@nongnu.org; Thu, 25 Apr 2013 22:48:03 -0400 Received: from mail-pa0-f47.google.com ([209.85.220.47]:44619) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVYhd-0007fQ-Ik for qemu-devel@nongnu.org; Thu, 25 Apr 2013 22:48:01 -0400 Received: by mail-pa0-f47.google.com with SMTP id bj3so178213pad.34 for ; Thu, 25 Apr 2013 19:48:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=9x7SvJ22QCFdBJqjIEEDOSs0VPf30xKucIjL0BaBd/o=; b=nAVpXDWrHCPDcKGMckn+gdxxL8kfYsVymVCFDy2nwwRfowjACJaOp55NZ4sJ3DiZvo FUoo9M1zIu7QZx2cxG14RwcMSOBA9DMtL22pk4iHcEZXn3rfhBofscSqUMIJZE/Weq6c NRSdPZ4l109KrRIXqmq0PkO4ZRG7aFv7S0dE2nPiGf5YZF80WKTz2MjQx93OJvhfDGEk QzY8i1rmrblIu+L4bn/wiOCrbJWHxrkYbQN/cZJyl36aXTXdzOAGs3h0d2Xgo3QrWL5Q jarspZW+RcM/+preacxJxHbPwLc/pYOVQjCAKtRig1zEsxa21IxCjLQ8xHwWklIbd7ej ceXA== X-Received: by 10.68.232.42 with SMTP id tl10mr56172876pbc.72.1366944480580; Thu, 25 Apr 2013 19:48:00 -0700 (PDT) Received: from localhost ([202.108.130.138]) by mx.google.com with ESMTPSA id to7sm10618368pab.0.2013.04.25.19.47.56 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Thu, 25 Apr 2013 19:47:59 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Fri, 26 Apr 2013 10:47:22 +0800 Message-Id: <1366944455-14239-2-git-send-email-qemulist@gmail.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1366944455-14239-1-git-send-email-qemulist@gmail.com> References: <1366944455-14239-1-git-send-email-qemulist@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.220.47 Cc: mdroth , Jan Kiszka , Stefan Hajnoczi , Anthony Liguori , Paolo Bonzini Subject: [Qemu-devel] [RFC PATCH v5 01/14] util: introduce gsource event abstraction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Liu Ping Fan Introduce two structs EventGSource, EventsGSource EventGSource is used to abstract the event with single backend file. EventsGSource is used to abstract the event with dynamically changed backend file, ex, slirp. Signed-off-by: Liu Ping Fan --- util/Makefile.objs | 1 + util/event_gsource.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/event_gsource.h | 49 +++++++++++++++ 3 files changed, 208 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..9cfdb4a --- /dev/null +++ b/util/event_gsource.c @@ -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 . + */ + +#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); +} + diff --git a/util/event_gsource.h b/util/event_gsource.h new file mode 100644 index 0000000..25b15d7 --- /dev/null +++ b/util/event_gsource.h @@ -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 . + */ + +#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