[alsa-devel] [PATCH 02/13] libhinawa: add hinawa context
Takashi Sakamoto
o-takashi at sakamocchi.jp
Tue Jan 27 16:35:22 CET 2015
On 2015年01月25日 20:34, Takashi Sakamoto wrote:
> In this library, 'transaction' consists of a pair of a request and
> a response. To achieve the transaction, a requester should wait for
> a response from the receiver.
>
> Typically, to achieve the transaction, applications which transfer
> requests are blocked with read(2) or poll(2) to wait responses. But
> this operation is not good for GUI applications because these
> blocking API stops a thread of event loop.
>
> To avoid this situation, this commit adds own 'context'. The context
> is running on own thread and execute poll(2). This context can be
> written directly with pthreads(7) and select(2)/poll(2)/epoll(7),
> but in this time I apply GMainContext/GThread in glib to save my
> time.
>
> Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
I realize this comment is bad. The strange circuit turned on in my brain
when creating this patch...
This library needs to handle any asynchronous events such as bus-reset
(from FireWire subsystem) or lock/unlock events (from ALSA), thus should
do poll regardless of transactions. In this reason, own thread is required.
> ---
> libhinawa/Makefile.am | 3 +++
> libhinawa/README | 1 +
> libhinawa/configure.ac | 7 +++++
> libhinawa/src/Makefile.am | 24 +++++++++++++++++
> libhinawa/src/hinawa_context.c | 60 ++++++++++++++++++++++++++++++++++++++++++
> libhinawa/src/hinawa_context.h | 10 +++++++
> 6 files changed, 105 insertions(+)
> create mode 100644 libhinawa/src/Makefile.am
> create mode 100644 libhinawa/src/hinawa_context.c
> create mode 100644 libhinawa/src/hinawa_context.h
>
> diff --git a/libhinawa/Makefile.am b/libhinawa/Makefile.am
> index e39f07b..05f5d58 100644
> --- a/libhinawa/Makefile.am
> +++ b/libhinawa/Makefile.am
> @@ -1,2 +1,5 @@
> # Include m4 macros
> ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
> +
> +SUBDIRS = \
> + src
> diff --git a/libhinawa/README b/libhinawa/README
> index 234ed91..db9b82a 100644
> --- a/libhinawa/README
> +++ b/libhinawa/README
> @@ -2,6 +2,7 @@ Requirements
> - GNU Autoconf 2.62 or later
> - GNU Automake 1.10.1 or later
> - GNU libtool 2.2.6 or later
> +- Glib 2.32.4 or later
>
> How to build
> $ ./autogen.sh
> diff --git a/libhinawa/configure.ac b/libhinawa/configure.ac
> index 2eeef0d..5ecb7ec 100644
> --- a/libhinawa/configure.ac
> +++ b/libhinawa/configure.ac
> @@ -19,6 +19,9 @@ AC_INIT([hinawa], [my_version], [o-takashi at sakamocchi.jp])
> AC_CONFIG_AUX_DIR([config])
> # The directory for M4 macros
> AC_CONFIG_MACRO_DIR([m4])
> +
> +# The directory for sources
> +AC_CONFIG_SRCDIR([src])
> # The header for variables with AC_DEFINE
> AC_CONFIG_HEADERS([config.h])
>
> @@ -39,9 +42,13 @@ AC_SUBST(LT_IFACE)
> # Detect C language compiler
> AC_PROG_CC
>
> +# Glib 2.32 or later
> +AM_PATH_GLIB_2_0([2.32.4], [], [], [gobject])
> +
> # The files generated from *.in
> AC_CONFIG_FILES([
> Makefile
> + src/Makefile
> ])
>
> # Generate scripts and launch
> diff --git a/libhinawa/src/Makefile.am b/libhinawa/src/Makefile.am
> new file mode 100644
> index 0000000..5673255
> --- /dev/null
> +++ b/libhinawa/src/Makefile.am
> @@ -0,0 +1,24 @@
> +# Remove auto-generated files when cleaning
> +CLEANFILES =
> +
> +AM_CPPFLAGS = \
> + -I$(top_builddir) \
> + -I$(top_srcdir)
> +
> +AM_CFLAGS = \
> + $(GLIB_CFLAGS) \
> + -Wall
> +
> +lib_LTLIBRARIES = \
> + libhinawa.la
> +
> +libhinawa_la_LDFLAGS = \
> + -version-info $(LT_IFACE)
> +
> +libhinawa_la_LIBADD = \
> + $(GLIB_LIBS)
> +
> +libhinawa_la_SOURCES = \
> + hinawa_context.c
> +
> +pkginclude_HEADERS =
> diff --git a/libhinawa/src/hinawa_context.c b/libhinawa/src/hinawa_context.c
> new file mode 100644
> index 0000000..dd20d21
> --- /dev/null
> +++ b/libhinawa/src/hinawa_context.c
> @@ -0,0 +1,60 @@
> +#include "hinawa_context.h"
> +
> +static GMainContext *ctx;
> +static GThread *thread;
> +
> +static gboolean running;
> +static gint counter;
> +
> +static gpointer run_main_loop(gpointer data)
> +{
> + while (running)
> + g_main_context_iteration(ctx, TRUE);
> +
> + g_thread_exit(NULL);
> +
> + return NULL;
> +}
> +
> +static GMainContext *get_my_context(GError **exception)
> +{
> + if (ctx == NULL)
> + ctx = g_main_context_new();
> +
> + if (thread == NULL) {
> + thread = g_thread_try_new("gmain", run_main_loop, NULL,
> + exception);
> + if (*exception != NULL) {
> + g_main_context_unref(ctx);
> + ctx = NULL;
> + }
> + }
> +
> + return ctx;
> +}
> +
> +gpointer hinawa_context_add_src(GSource *src, gint fd, GIOCondition event,
> + GError **exception)
> +{
> + GMainContext *ctx;
> +
> + ctx = get_my_context(exception);
> + if (*exception != NULL)
> + return NULL;
> + running = TRUE;
> +
> + /* NOTE: The returned ID is never used. */
> + g_source_attach(src, ctx);
> +
> + return g_source_add_unix_fd(src, fd, event);
> +}
> +
> +void hinawa_context_remove_src(GSource *src)
> +{
> + g_source_destroy(src);
> + if (g_atomic_int_dec_and_test(&counter)) {
> + running = FALSE;
> + g_thread_join(thread);
> + thread = NULL;
> + }
> +}
> diff --git a/libhinawa/src/hinawa_context.h b/libhinawa/src/hinawa_context.h
> new file mode 100644
> index 0000000..97666c6
> --- /dev/null
> +++ b/libhinawa/src/hinawa_context.h
> @@ -0,0 +1,10 @@
> +#ifndef __ALSA_TOOLS_HINAWA_CONTEXT_H__
> +#define __ALSA_TOOLS_HINAWA_CONTEXT_H__
> +
> +#include <glib.h>
> +#include <glib-object.h>
> +
> +gpointer hinawa_context_add_src(GSource *src, gint fd, GIOCondition event,
> + GError **exception);
> +
> +#endif
>
More information about the Alsa-devel
mailing list