[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