[alsa-devel] [RFCv3][PATCH 22/39] axfer: add a common interface of waiter for I/O event notification
Takashi Sakamoto
o-takashi at sakamocchi.jp
Mon Oct 2 02:19:23 CEST 2017
There're several types of system calls for multiplexed I/O. They're used to
receive notifications of I/O events. Typically, userspace applications call
them against file descriptor to yield CPU. When I/O is enabled on any of
the descriptors, a task of the application is rescheduled, then the
application execute I/O calls.
This commit adds a common interface for this type of system calls, named as
'waiter'. This is expected to be used with non-blocking file operation and
operations on mapped page frame.
Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
axfer/Makefile.am | 7 ++++--
axfer/waiter.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
axfer/waiter.h | 45 +++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 2 deletions(-)
create mode 100644 axfer/waiter.c
create mode 100644 axfer/waiter.h
diff --git a/axfer/Makefile.am b/axfer/Makefile.am
index b378442b..f290cca8 100644
--- a/axfer/Makefile.am
+++ b/axfer/Makefile.am
@@ -21,7 +21,8 @@ noinst_HEADERS = \
mapper.h
options.h \
xfer.h \
- xfer-alsa.h
+ xfer-alsa.h \
+ waiter.h
axfer_SOURCES = \
misc.h \
@@ -45,4 +46,6 @@ axfer_SOURCES = \
xfer-libasound.h \
xfer-libasound.c \
xfer-libasound-irq-rw.c \
- subcmd-transfer.c
+ subcmd-transfer.c \
+ waiter.h \
+ waiter.c
diff --git a/axfer/waiter.c b/axfer/waiter.c
new file mode 100644
index 00000000..dfe42f84
--- /dev/null
+++ b/axfer/waiter.c
@@ -0,0 +1,66 @@
+/*
+ * waiter.c - I/O event waiter.
+ *
+ * Copyright (c) 2017 Takashi Sakamoto <o-takashi at sakamocchi.jp>
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include "waiter.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "misc.h"
+
+int waiter_context_init(struct waiter_context *waiter, enum waiter_type type)
+{
+ struct {
+ enum waiter_type type;
+ const struct waiter_data *waiter;
+ } entries[] = {
+ {WAITER_TYPE_COUNT, NULL},
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(entries); ++i) {
+ if (entries[i].type == type)
+ break;
+ }
+ if (i == ARRAY_SIZE(entries))
+ return -EINVAL;
+
+ waiter->private_data = malloc(entries[i].waiter->private_size);
+ if (waiter->private_data == NULL)
+ return -ENOMEM;
+ memset(waiter->private_data, 0, entries[i].waiter->private_size);
+
+ waiter->type = type;
+ waiter->ops = &entries[i].waiter->ops;
+
+ return 0;
+}
+
+int waiter_context_prepare(struct waiter_context *waiter, int *fds,
+ unsigned int fd_count)
+{
+ return waiter->ops->prepare(waiter, fds, fd_count);
+}
+
+int waiter_context_wait_event(struct waiter_context *waiter, int timeout_msec)
+{
+ return waiter->ops->wait_event(waiter, timeout_msec);
+}
+
+void waiter_context_release(struct waiter_context *waiter)
+{
+ waiter->ops->release(waiter);
+}
+
+void waiter_context_destroy(struct waiter_context *waiter)
+{
+ if (waiter->private_data)
+ free(waiter->private_data);
+ waiter->private_data = NULL;
+}
diff --git a/axfer/waiter.h b/axfer/waiter.h
new file mode 100644
index 00000000..dbd7ca70
--- /dev/null
+++ b/axfer/waiter.h
@@ -0,0 +1,45 @@
+/*
+ * waiter.h - a header for I/O event waiter.
+ *
+ * Copyright (c) 2017 Takashi Sakamoto <o-takashi at sakamocchi.jp>
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#ifndef __ALSA_UTILS_AXFER_WAITER__H_
+#define __ALSA_UTILS_AXFER_WAITER__H_
+
+enum waiter_type {
+ WAITER_TYPE_COUNT,
+};
+
+struct waiter_ops;
+
+struct waiter_context {
+ enum waiter_type type;
+ const struct waiter_ops *ops;
+ void *private_data;
+};
+
+int waiter_context_init(struct waiter_context *waiter, enum waiter_type type);
+int waiter_context_prepare(struct waiter_context *waiter, int *fds,
+ unsigned int fd_count);
+int waiter_context_wait_event(struct waiter_context *waiter, int timeout_msec);
+void waiter_context_release(struct waiter_context *waiter);
+void waiter_context_destroy(struct waiter_context *waiter);
+
+/* For internal use in 'waiter' module. */
+
+struct waiter_ops {
+ int (*prepare)(struct waiter_context *waiter, int *fds,
+ unsigned int fd_count);
+ int (*wait_event)(struct waiter_context *waiter, int timeout_msec);
+ void (*release)(struct waiter_context *waiter);
+};
+
+struct waiter_data {
+ struct waiter_ops ops;
+ unsigned int private_size;
+};
+
+#endif
--
2.11.0
More information about the Alsa-devel
mailing list