From patchwork Wed Apr 17 08:39:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 237168 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 594202C0145 for ; Wed, 17 Apr 2013 18:41:48 +1000 (EST) Received: from localhost ([::1]:35584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1USNw2-0000xv-IM for incoming@patchwork.ozlabs.org; Wed, 17 Apr 2013 04:41:46 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50263) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1USNuC-0007zS-7l for qemu-devel@nongnu.org; Wed, 17 Apr 2013 04:39:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1USNu7-0002iS-1e for qemu-devel@nongnu.org; Wed, 17 Apr 2013 04:39:52 -0400 Received: from mail-gg0-x233.google.com ([2607:f8b0:4002:c02::233]:61253) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1USNu6-0002iK-SF for qemu-devel@nongnu.org; Wed, 17 Apr 2013 04:39:46 -0400 Received: by mail-gg0-f179.google.com with SMTP id o4so53690ggm.24 for ; Wed, 17 Apr 2013 01:39:46 -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=YsAnvDv5h7JaPwcWFka4Lajv8BJ1/af4bwiDAXAugfE=; b=PF5nAWQj3p+KlXe+EGCXivFly1hH1vYVDvIieFM2b00xKfkZkj7fcXLz9w4qPlqEKk gZBCMD5myaWUEmjRnqKPC5A0Ur1n+NltnENikDLIWL1OqvZFeG5wYoBedg+D/vskbkaP vdMDnQhZFPFLFEnNrAlNsiHL8HLzQ8eaJbuwjA6FysIDfhYBp7qW/Wy5RgaPTjeLWucl ECWqZQYVigaASAF9TAZZGq+6bUAfZRMNbDZNyzRJmwONV3rIhtJODOBYi3MwUAATDPIx EGYyiEU48c7lj30nPUfIwMdvtvvHCocHO3aMYmgXfk1RpOphG4oo0FAxZ3PNvtp54/SR rNSw== X-Received: by 10.236.147.75 with SMTP id s51mr3163263yhj.33.1366187986376; Wed, 17 Apr 2013 01:39:46 -0700 (PDT) Received: from localhost ([114.245.251.229]) by mx.google.com with ESMTPS id f70sm8033624yhi.12.2013.04.17.01.39.41 (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Wed, 17 Apr 2013 01:39:45 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Wed, 17 Apr 2013 16:39:10 +0800 Message-Id: <1366187964-14265-2-git-send-email-qemulist@gmail.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1366187964-14265-1-git-send-email-qemulist@gmail.com> References: <1366187964-14265-1-git-send-email-qemulist@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c02::233 Cc: mdroth , Paolo Bonzini , Stefan Hajnoczi , Anthony Liguori , Jan Kiszka Subject: [Qemu-devel] [RFC PATCH v4 01/15] util: introduce gsource event abstration 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 dynamicly changed backend file, ex, slirp. Signed-off-by: Liu Ping Fan --- 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 . + */ + +#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 . + */ + +#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