[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 05/10] Introduce QemuEvent abstraction
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v3 05/10] Introduce QemuEvent abstraction |
Date: |
Thu, 5 Apr 2012 12:59:12 +0200 |
Provide generic services for binary events. Blocking wait would be
feasible but is not included yet as there are no users.
Signed-off-by: Jan Kiszka <address@hidden>
---
Makefile | 2 +-
Makefile.objs | 5 ++-
qemu-event-posix.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-event-win32.c | 65 ++++++++++++++++++++++++++++++
qemu-thread-posix.h | 5 ++
qemu-thread-win32.h | 4 ++
qemu-thread.h | 12 ++++++
7 files changed, 201 insertions(+), 2 deletions(-)
create mode 100644 qemu-event-posix.c
create mode 100644 qemu-event-win32.c
diff --git a/Makefile b/Makefile
index 35c7a2a..ea127f9 100644
--- a/Makefile
+++ b/Makefile
@@ -153,7 +153,7 @@ endif
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o:
$(GENERATED_HEADERS)
-tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
+tools-obj-y = $(oslib-obj-y) $(event-obj-y) $(trace-obj-y) qemu-tool.o
qemu-timer.o \
qemu-timer-common.o main-loop.o notify.o iohandler.o cutils.o async.o
tools-obj-$(CONFIG_POSIX) += compatfd.o
diff --git a/Makefile.objs b/Makefile.objs
index f308b57..377bfe2 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -24,6 +24,9 @@ oslib-obj-y = osdep.o
oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
+event-obj-$(CONFIG_POSIX) = qemu-event-posix.o
+event-obj-$(CONFIG_WIN32) = qemu-event-win32.o
+
#######################################################################
# coroutines
coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
@@ -97,7 +100,7 @@ common-obj-y += $(net-obj-y)
common-obj-y += $(qom-obj-twice-y)
common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
common-obj-y += readline.o console.o cursor.o
-common-obj-y += $(oslib-obj-y)
+common-obj-y += $(oslib-obj-y) $(event-obj-y)
common-obj-$(CONFIG_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o
diff --git a/qemu-event-posix.c b/qemu-event-posix.c
new file mode 100644
index 0000000..6138168
--- /dev/null
+++ b/qemu-event-posix.c
@@ -0,0 +1,110 @@
+/*
+ * Posix implementations of event signaling service
+ *
+ * Copyright Red Hat, Inc. 2012
+ * Copyright Siemens AG 2012
+ *
+ * Author:
+ * Paolo Bonzini <address@hidden>
+ * Jan Kiszka <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-thread.h"
+#include "qemu-common.h"
+#include "main-loop.h"
+
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
+void qemu_event_init(QemuEvent *event, bool signaled)
+{
+ int fds[2];
+ int ret;
+
+#ifdef CONFIG_EVENTFD
+ ret = eventfd(signaled, EFD_NONBLOCK | EFD_CLOEXEC);
+ if (ret >= 0) {
+ event->rfd = ret;
+ event->wfd = dup(ret);
+ if (event->wfd < 0) {
+ qemu_error_exit(errno, __func__);
+ }
+ qemu_set_cloexec(event->wfd);
+ return;
+ }
+ if (errno != ENOSYS) {
+ qemu_error_exit(errno, __func__);
+ }
+ /* fall back to pipe-based support */
+#endif
+
+ ret = qemu_pipe(fds);
+ if (ret < 0) {
+ qemu_error_exit(errno, __func__);
+ }
+ event->rfd = fds[0];
+ event->wfd = fds[1];
+ if (signaled) {
+ qemu_event_signal(event);
+ }
+}
+
+void qemu_event_destroy(QemuEvent *event)
+{
+ close(event->rfd);
+ close(event->wfd);
+}
+
+int qemu_event_get_signal_fd(QemuEvent *event)
+{
+ return event->wfd;
+}
+
+int qemu_event_get_poll_fd(QemuEvent *event)
+{
+ return event->rfd;
+}
+
+void qemu_event_set_handler(QemuEvent *event, QemuEventHandler *handler,
+ void *opaque)
+{
+ qemu_set_fd_handler2(event->rfd, NULL, (IOHandler *)handler, NULL, opaque);
+}
+
+void qemu_event_signal(QemuEvent *event)
+{
+ /* Write 8 bytes to be compatible with eventfd. */
+ static const uint64_t val = 1;
+ ssize_t ret;
+
+ do {
+ ret = write(event->wfd, &val, sizeof(val));
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0 && errno != EAGAIN) {
+ qemu_error_exit(errno, __func__);
+ }
+}
+
+bool qemu_event_consume(QemuEvent *event)
+{
+ bool was_set = false;
+ uint64_t val;
+ int ret;
+
+ while (1) {
+ ret = read(event->rfd, &val, sizeof(val));
+ if (ret == sizeof(val)) {
+ was_set = true;
+ continue;
+ }
+ if (ret < 0 && errno == EAGAIN) {
+ return was_set;
+ }
+ qemu_error_exit(errno, __func__);
+ }
+}
diff --git a/qemu-event-win32.c b/qemu-event-win32.c
new file mode 100644
index 0000000..38fe9ae
--- /dev/null
+++ b/qemu-event-win32.c
@@ -0,0 +1,65 @@
+/*
+ * Win32 implementations of event signaling service
+ *
+ * Copyright Red Hat, Inc. 2012
+ * Copyright Siemens AG 2012
+ *
+ * Author:
+ * Paolo Bonzini <address@hidden>
+ * Jan Kiszka <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 <stdbool.h>
+#include "qemu-thread.h"
+#include "qemu-common.h"
+#include "main-loop.h"
+
+void qemu_event_init(QemuEvent *event, bool signaled)
+{
+ event->event = CreateEvent(NULL, FALSE, signaled, NULL);
+ if (!event->event) {
+ qemu_error_exit(GetLastError(), __func__);
+ }
+}
+
+void qemu_event_destroy(QemuEvent *event)
+{
+ CloseHandle(event->event);
+}
+
+int qemu_event_get_signal_fd(QemuEvent *event)
+{
+ /* unsupported on Win32 */
+ abort();
+}
+
+void qemu_event_set_handler(QemuEvent *event, QemuEventHandler *handler,
+ void *opaque)
+{
+ if (handler) {
+ qemu_add_wait_object(event->event, (IOHandler *)handler, opaque);
+ } else {
+ qemu_del_wait_object(event->event, (IOHandler *)handler, opaque);
+ }
+}
+
+void qemu_event_signal(QemuEvent *event)
+{
+ if (!SetEvent(event->event)) {
+ qemu_error_exit(GetLastError(), __func__);
+ }
+}
+
+bool qemu_event_consume(QemuEvent *event)
+{
+ DWORD ret;
+
+ ret = WaitForSingleObject(event->event, 0);
+ if (ret == WAIT_FAILED) {
+ qemu_error_exit(GetLastError(), __func__);
+ }
+ return ret == WAIT_OBJECT_0;
+}
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
index 9f00524..95fbb45 100644
--- a/qemu-thread-posix.h
+++ b/qemu-thread-posix.h
@@ -11,6 +11,11 @@ struct QemuCond {
pthread_cond_t cond;
};
+struct QemuEvent {
+ int rfd;
+ int wfd;
+};
+
struct QemuThread {
pthread_t thread;
};
diff --git a/qemu-thread-win32.h b/qemu-thread-win32.h
index b9d1be8..d1b7631 100644
--- a/qemu-thread-win32.h
+++ b/qemu-thread-win32.h
@@ -13,6 +13,10 @@ struct QemuCond {
HANDLE continue_event;
};
+struct QemuEvent {
+ HANDLE event;
+};
+
typedef struct QemuThreadData QemuThreadData;
struct QemuThread {
QemuThreadData *data;
diff --git a/qemu-thread.h b/qemu-thread.h
index 10f2c51..a53384f 100644
--- a/qemu-thread.h
+++ b/qemu-thread.h
@@ -5,8 +5,11 @@
typedef struct QemuMutex QemuMutex;
typedef struct QemuCond QemuCond;
+typedef struct QemuEvent QemuEvent;
typedef struct QemuThread QemuThread;
+typedef void QemuEventHandler(void *opaque);
+
#ifdef _WIN32
#include "qemu-thread-win32.h"
#else
@@ -28,6 +31,15 @@ void qemu_mutex_unlock(QemuMutex *mutex);
void qemu_cond_init(QemuCond *cond);
void qemu_cond_destroy(QemuCond *cond);
+void qemu_event_init(QemuEvent *event, bool signaled);
+void qemu_event_destroy(QemuEvent *event);
+int qemu_event_get_signal_fd(QemuEvent *event);
+int qemu_event_get_poll_fd(QemuEvent *event);
+void qemu_event_set_handler(QemuEvent *event, QemuEventHandler *handler,
+ void *opaque);
+void qemu_event_signal(QemuEvent *event);
+bool qemu_event_consume(QemuEvent *event);
+
/*
* IMPORTANT: The implementation does not guarantee that pthread_cond_signal
* and pthread_cond_broadcast can be called except while the same mutex is
--
1.7.3.4
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, (continued)
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, Paolo Bonzini, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, Jan Kiszka, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, malc, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, Jan Kiszka, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, malc, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, Jan Kiszka, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, malc, 2012/04/05
- Re: [Qemu-devel] [PATCH v3 01/10] Introduce qemu_cond_timedwait for POSIX, malc, 2012/04/05
[Qemu-devel] [PATCH v3 04/10] qemu-thread: Factor out qemu_error_exit, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 03/10] Switch compatfd to QEMU thread, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 05/10] Introduce QemuEvent abstraction,
Jan Kiszka <=
[Qemu-devel] [PATCH v3 02/10] Switch POSIX compat AIO to QEMU abstractions, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 06/10] Use QemuEvent in main loop, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 07/10] Drop unused qemu_eventfd, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 10/10] Remove EventNotifier, Jan Kiszka, 2012/04/05
[Qemu-devel] [PATCH v3 08/10] Use QemuEvent for POSIX AIO, Jan Kiszka, 2012/04/05