[alsa-devel] [RFCv2][PATCH 22/38] axfer: add a common interface of waiter for I/O event notification

Takashi Sakamoto o-takashi at sakamocchi.jp
Tue Sep 19 02:44:02 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, process 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