[PATCH 16/25] efw-downloader: node_dispatcher: add event dispatcher utilizing GLib MainContext/MainLoop
Takashi Sakamoto
o-takashi at sakamocchi.jp
Fri Aug 21 09:31:02 CEST 2020
HinawaFwNode creates GSource for GLib MainContext. It's easy to GLib
MainLoop as event dispatcher.
This commit adds local application of GLib MainContext/MainLoop to dispatch
events for HinawaFwNode.
Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
efw-downloader/src/meson.build | 2 +
efw-downloader/src/node-dispatcher.c | 86 ++++++++++++++++++++++++++++
efw-downloader/src/node-dispatcher.h | 21 +++++++
efw-downloader/src/subcmd-device.c | 10 ++++
4 files changed, 119 insertions(+)
create mode 100644 efw-downloader/src/node-dispatcher.c
create mode 100644 efw-downloader/src/node-dispatcher.h
diff --git a/efw-downloader/src/meson.build b/efw-downloader/src/meson.build
index c006c8b..c43c332 100644
--- a/efw-downloader/src/meson.build
+++ b/efw-downloader/src/meson.build
@@ -15,12 +15,14 @@ sources = [
'main.c',
'efw-proto.c',
'config-rom.c',
+ 'node-dispatcher.c',
'subcmd-device.c',
]
headers = [
'efw-proto.h',
'config-rom.h',
+ 'node-dispatcher.h',
'subcmds.h',
]
diff --git a/efw-downloader/src/node-dispatcher.c b/efw-downloader/src/node-dispatcher.c
new file mode 100644
index 0000000..8394600
--- /dev/null
+++ b/efw-downloader/src/node-dispatcher.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright (c) 2020 Takashi Sakamoto
+#include "node-dispatcher.h"
+#include <time.h>
+
+struct thread_arg {
+ GMainLoop *loop;
+ GCond cond;
+ GMutex mutex;
+};
+
+static gpointer run_node_dispatcher(gpointer data)
+{
+ struct thread_arg *args = (struct thread_arg *)data;
+
+ g_mutex_lock(&args->mutex);
+ g_cond_signal(&args->cond);
+ g_mutex_unlock(&args->mutex);
+
+ g_main_loop_run(args->loop);
+
+ return NULL;
+}
+
+void node_dispatcher_start(struct node_dispatcher *dispatcher, HinawaFwNode *node, GError **error)
+{
+ struct thread_arg args;
+ GSource *src;
+
+ dispatcher->ctx = g_main_context_new();
+
+ hinawa_fw_node_create_source(node, &src, error);
+ if (*error != NULL)
+ return;
+
+ g_source_attach(src, dispatcher->ctx);
+ g_source_unref(src);
+
+ dispatcher->loop = g_main_loop_new(dispatcher->ctx, FALSE);
+
+ args.loop = dispatcher->loop;
+ g_cond_init(&args.cond);
+ g_mutex_init(&args.mutex);
+
+ dispatcher->th = g_thread_try_new("node-dispatcher", run_node_dispatcher, &args, error);
+ if (*error != NULL) {
+ g_main_loop_quit(dispatcher->loop);
+ g_main_loop_unref(dispatcher->loop);
+ dispatcher->loop = NULL;
+
+ g_main_context_unref(dispatcher->ctx);
+ dispatcher->ctx = NULL;
+
+ goto end;
+ }
+
+ g_mutex_lock(&args.mutex);
+ while (!g_main_loop_is_running(dispatcher->loop))
+ g_cond_wait(&args.cond, &args.mutex);
+ g_mutex_unlock(&args.mutex);
+end:
+ g_cond_clear(&args.cond);
+ g_mutex_clear(&args.mutex);
+}
+
+void node_dispatcher_stop(struct node_dispatcher *dispatcher)
+{
+ if (dispatcher->loop != NULL)
+ g_main_loop_quit(dispatcher->loop);
+
+ if (dispatcher->th != NULL) {
+ g_thread_join(dispatcher->th);
+ g_thread_unref(dispatcher->th);
+ dispatcher->th = NULL;
+ }
+
+ if (dispatcher->loop != NULL) {
+ g_main_loop_unref(dispatcher->loop);
+ dispatcher->loop = NULL;
+ }
+
+ if (dispatcher->ctx != NULL) {
+ g_main_context_unref(dispatcher->ctx);
+ dispatcher->ctx = NULL;
+ }
+}
diff --git a/efw-downloader/src/node-dispatcher.h b/efw-downloader/src/node-dispatcher.h
new file mode 100644
index 0000000..9e47e00
--- /dev/null
+++ b/efw-downloader/src/node-dispatcher.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright (c) 2020 Takashi Sakamoto
+#ifndef __NODE_DISPATCHER_H__
+#define __NODE_DISPATCHER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libhinawa/fw_node.h>
+#include <libhinawa/fw_resp.h>
+
+struct node_dispatcher {
+ GMainContext *ctx;
+ GMainLoop *loop;
+ GThread *th;
+};
+
+void node_dispatcher_start(struct node_dispatcher *dispatcher, HinawaFwNode *node, GError **error);
+void node_dispatcher_stop(struct node_dispatcher *dispatcher);
+
+#endif
diff --git a/efw-downloader/src/subcmd-device.c b/efw-downloader/src/subcmd-device.c
index 1bfa1f2..5ac0ac6 100644
--- a/efw-downloader/src/subcmd-device.c
+++ b/efw-downloader/src/subcmd-device.c
@@ -7,6 +7,7 @@
#include "efw-proto.h"
#include "config-rom.h"
+#include "node-dispatcher.h"
#define report_error(error, msg) \
fprintf(stderr, "Fail to %s: %s %d %s\n", \
@@ -60,6 +61,7 @@ int subcmd_device(int argc, char **argv)
gsize length;
guint32 vendor_id, model_id;
EfwProto *proto;
+ struct node_dispatcher dispatcher = {0};
int err;
int i;
@@ -116,8 +118,16 @@ int subcmd_device(int argc, char **argv)
goto err_node;
}
+ node_dispatcher_start(&dispatcher, node, &error);
+ if (error != NULL) {
+ report_error(error, "begin dispatcher");
+ goto err_proto;
+ }
+
entry->op(argc, argv, proto, &error);
+ node_dispatcher_stop(&dispatcher);
+err_proto:
efw_proto_unbind(proto);
g_object_unref(proto);
err_node:
--
2.25.1
More information about the Alsa-devel
mailing list