[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH for-2.3 1/5] poll: Introduce QEMU Poll API
From: |
Fam Zheng |
Subject: |
[Qemu-devel] [PATCH for-2.3 1/5] poll: Introduce QEMU Poll API |
Date: |
Tue, 25 Nov 2014 16:07:55 +0800 |
This is abstract of underlying poll implementation. A glib
implementation is included.
Signed-off-by: Fam Zheng <address@hidden>
---
Makefile.objs | 2 +-
include/qemu/poll.h | 40 +++++++++++++++
include/qemu/typedefs.h | 2 +
poll-glib.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 173 insertions(+), 1 deletion(-)
create mode 100644 include/qemu/poll.h
create mode 100644 poll-glib.c
diff --git a/Makefile.objs b/Makefile.objs
index 18fd35c..57184eb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -9,7 +9,7 @@ util-obj-y = util/ qobject/ qapi/ qapi-types.o qapi-visit.o
qapi-event.o
block-obj-y = async.o thread-pool.o
block-obj-y += nbd.o block.o blockjob.o
block-obj-y += main-loop.o iohandler.o qemu-timer.o
-block-obj-$(CONFIG_POSIX) += aio-posix.o
+block-obj-$(CONFIG_POSIX) += aio-posix.o poll-glib.o
block-obj-$(CONFIG_WIN32) += aio-win32.o
block-obj-y += block/
block-obj-y += qemu-io-cmds.o
diff --git a/include/qemu/poll.h b/include/qemu/poll.h
new file mode 100644
index 0000000..597975f
--- /dev/null
+++ b/include/qemu/poll.h
@@ -0,0 +1,40 @@
+#ifndef QEMU_POLL_H
+#define QEMU_POLL_H
+
+#include "qemu/typedefs.h"
+#include "qemu-common.h"
+
+struct QEMUPollEvent {
+ int fd;
+ int events;
+ int revents;
+ void *opaque;
+};
+
+QEMUPoll *qemu_poll_new(void);
+void qemu_poll_free(QEMUPoll *qpoll);
+int qemu_poll(QEMUPoll *qpoll, int64_t timeout_ns);
+
+/* Add an fd to poll. Return -EEXIST if fd already registered. */
+int qemu_poll_add(QEMUPoll *qpoll, int fd, int gio_events, void *opaque);
+
+/* Delete a previously added fd. Return -ENOENT if fd not registered. */
+int qemu_poll_del(QEMUPoll *qpoll, int fd);
+
+/**
+ * A shortcut to:
+ * 1) remove all the existing fds;
+ * 2) add all in @fds, while setting each fd's opaque pointer to the pollfd
+ * struct itself.
+ */
+int qemu_poll_set_fds(QEMUPoll *qpoll, GPollFD *fds, int nfds);
+
+/**
+ * Query the events from last qemu_poll. ONLY revent and opaque are valid in
+ * @events after return.
+ */
+int qemu_poll_get_events(QEMUPoll *qpoll,
+ QEMUPollEvent *events,
+ int max_events);
+
+#endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 3475177..f9a5e60 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -7,6 +7,8 @@ typedef struct QEMUTimer QEMUTimer;
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
typedef struct QEMUFile QEMUFile;
typedef struct QEMUBH QEMUBH;
+typedef struct QEMUPoll QEMUPoll;
+typedef struct QEMUPollEvent QEMUPollEvent;
typedef struct AioContext AioContext;
diff --git a/poll-glib.c b/poll-glib.c
new file mode 100644
index 0000000..64fde69
--- /dev/null
+++ b/poll-glib.c
@@ -0,0 +1,130 @@
+/*
+ * g_poll implementation for QEMU Poll API
+ *
+ * Copyright Red Hat, Inc. 2014
+ *
+ * Authors:
+ * Fam Zheng <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include "qemu/poll.h"
+
+struct QEMUPoll {
+ /* Array of GPollFD for g_poll() */
+ GArray *gpollfds;
+
+ /* Array of opaque pointers, should be in sync with gpollfds */
+ GArray *opaque;
+};
+
+QEMUPoll *qemu_poll_new(void)
+{
+ QEMUPoll *qpoll = g_new0(QEMUPoll, 1);
+ qpoll->gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
+ qpoll->opaque = g_array_new(FALSE, FALSE, sizeof(void *));
+ return qpoll;
+}
+
+
+void qemu_poll_free(QEMUPoll *qpoll)
+{
+ g_array_unref(qpoll->gpollfds);
+ g_array_unref(qpoll->opaque);
+ g_free(qpoll);
+}
+
+int qemu_poll(QEMUPoll *qpoll, int64_t timeout_ns)
+{
+ int i;
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ p->revents = 0;
+ }
+ return g_poll((GPollFD *)qpoll->gpollfds->data,
+ qpoll->gpollfds->len,
+ qemu_timeout_ns_to_ms(timeout_ns));
+}
+
+/* Add an fd to poll. Return -EEXIST if fd already registered. */
+int qemu_poll_add(QEMUPoll *qpoll, int fd, int gio_events, void *opaque)
+{
+ int i;
+ GPollFD pfd = (GPollFD) {
+ .fd = fd,
+ .revents = 0,
+ .events = gio_events,
+ };
+
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (p->fd == fd) {
+ return -EEXIST;
+ }
+ }
+ g_array_append_val(qpoll->gpollfds, pfd);
+ g_array_append_val(qpoll->opaque, opaque);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ return 0;
+}
+
+/* Delete a previously added fd. Return -ENOENT if fd not registered. */
+int qemu_poll_del(QEMUPoll *qpoll, int fd)
+{
+ int i;
+ int found = -1;
+
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (p->fd == fd) {
+ found = i;
+ break;
+ }
+ }
+ if (found >= 0) {
+ g_array_remove_index(qpoll->gpollfds, found);
+ g_array_remove_index(qpoll->opaque, found);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ return 0;
+ } else {
+ return -ENOENT;
+ }
+}
+
+int qemu_poll_set_fds(QEMUPoll *qpoll, GPollFD *fds, int nfds)
+{
+ int i;
+ g_array_set_size(qpoll->gpollfds, 0);
+ g_array_set_size(qpoll->opaque, 0);
+ for (i = 0; i < nfds; i++) {
+ void *opaque = &fds[i];
+ g_array_append_val(qpoll->gpollfds, fds[i]);
+ g_array_append_val(qpoll->opaque, opaque);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ }
+ return nfds;
+}
+
+int qemu_poll_get_events(QEMUPoll *qpoll,
+ QEMUPollEvent *events,
+ int max_events)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < qpoll->gpollfds->len && r < max_events; i++) {
+ GPollFD *fd = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (fd->revents & fd->events) {
+ events[r].fd = fd->fd;
+ events[r].revents = fd->revents;
+ events[r].events = fd->events;
+ events[r].opaque = g_array_index(qpoll->opaque, void *, i);
+ r++;
+ }
+ }
+ return r;
+}
--
1.9.3
- [Qemu-devel] [PATCH for-2.3 0/5] aio: Support epoll by introducing qemu_poll abstraction, Fam Zheng, 2014/11/25
- [Qemu-devel] [PATCH for-2.3 1/5] poll: Introduce QEMU Poll API,
Fam Zheng <=
- [Qemu-devel] [PATCH for-2.3 3/5] poll: Add epoll implementation for qemu_poll, Fam Zheng, 2014/11/25
- [Qemu-devel] [PATCH for-2.3 2/5] posix-aio: Use QEMU poll interface, Fam Zheng, 2014/11/25
- [Qemu-devel] [PATCH for-2.3 4/5] main-loop: Replace qemu_poll_ns with qemu_poll, Fam Zheng, 2014/11/25
- [Qemu-devel] [PATCH for-2.3 5/5] tests: Add test case for qemu_poll, Fam Zheng, 2014/11/25
- Re: [Qemu-devel] [PATCH for-2.3 0/5] aio: Support epoll by introducing qemu_poll abstraction, Stefan Hajnoczi, 2014/11/25