[alsa-devel] [RFCv2][PATCH 23/38] axfer: add support of waiter for poll(2)

Takashi Sakamoto o-takashi at sakamocchi.jp
Tue Sep 19 02:44:03 CEST 2017


This commit adds support for poll(2) system call.

Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
 axfer/Makefile.am   |  3 ++-
 axfer/waiter-poll.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 axfer/waiter.c      |  2 +-
 axfer/waiter.h      |  3 +++
 4 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 axfer/waiter-poll.c

diff --git a/axfer/Makefile.am b/axfer/Makefile.am
index f290cca8..a4e9f1bc 100644
--- a/axfer/Makefile.am
+++ b/axfer/Makefile.am
@@ -48,4 +48,5 @@ axfer_SOURCES = \
 	xfer-libasound-irq-rw.c \
 	subcmd-transfer.c \
 	waiter.h \
-	waiter.c
+	waiter.c \
+	waiter-poll.c
diff --git a/axfer/waiter-poll.c b/axfer/waiter-poll.c
new file mode 100644
index 00000000..70813ee0
--- /dev/null
+++ b/axfer/waiter-poll.c
@@ -0,0 +1,68 @@
+/*
+ * waiter-waiter-poll.c - Waiter for event notification by poll(2).
+ *
+ * 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 "misc.h"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <poll.h>
+
+struct poll_state {
+	struct pollfd *pfds;
+	unsigned int count;
+};
+
+static int poll_prepare(struct waiter_context *waiter, int *fds,
+			unsigned int fd_count)
+{
+	struct poll_state *state = waiter->private_data;
+	int i;
+
+	state->pfds = calloc(fd_count, sizeof(struct pollfd));
+	if (state->pfds == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < fd_count; ++i) {
+		state->pfds[i].fd = fds[i];
+		state->pfds[i].events = POLLIN | POLLOUT;
+	}
+
+	state->count = fd_count;
+
+	return 0;
+}
+
+static int poll_wait_event(struct waiter_context *waiter, int timeout_msec)
+{
+	struct poll_state *state = waiter->private_data;
+	int err;
+
+	err = poll(state->pfds, state->count, timeout_msec);
+	if (err < 0)
+		return -errno;
+
+	return 0;
+}
+
+static void poll_release(struct waiter_context *waiter)
+{
+	struct poll_state *state = waiter->private_data;
+
+	free(state->pfds);
+	state->pfds = 0;
+}
+
+const struct waiter_data waiter_poll = {
+	.ops = {
+		.prepare	= poll_prepare,
+		.wait_event	= poll_wait_event,
+		.release	= poll_release,
+	},
+	.private_size = sizeof(struct poll_state),
+};
diff --git a/axfer/waiter.c b/axfer/waiter.c
index dfe42f84..045b7f31 100644
--- a/axfer/waiter.c
+++ b/axfer/waiter.c
@@ -20,7 +20,7 @@ int waiter_context_init(struct waiter_context *waiter, enum waiter_type type)
 		enum waiter_type type;
 		const struct waiter_data *waiter;
 	} entries[] = {
-		{WAITER_TYPE_COUNT,	NULL},
+		{WAITER_TYPE_POLL, &waiter_poll},
 	};
 	int i;
 
diff --git a/axfer/waiter.h b/axfer/waiter.h
index dbd7ca70..00147f45 100644
--- a/axfer/waiter.h
+++ b/axfer/waiter.h
@@ -10,6 +10,7 @@
 #define __ALSA_UTILS_AXFER_WAITER__H_
 
 enum waiter_type {
+	WAITER_TYPE_POLL = 0,
 	WAITER_TYPE_COUNT,
 };
 
@@ -42,4 +43,6 @@ struct waiter_data {
 	unsigned int private_size;
 };
 
+extern const struct waiter_data waiter_poll;
+
 #endif
-- 
2.11.0



More information about the Alsa-devel mailing list