summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--irmp/irmp-main-sharedlib.c112
-rw-r--r--irmp/irmp-main-sharedlib.h44
4 files changed, 159 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 9e15c30..32c6dd6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,6 +64,8 @@ libirmp_la_SOURCES = \
irmp/irmpsystem.h \
irmp/irmpprotocols.h
noinst_HEADERS += irmp/irmp.c
+libirmp_la_CFLAGS = $(LIBIRMP_CFLAGS)
+libirmp_la_LIBADD = $(LIBIRMP_LIBS)
libirmp_la_LDFLAGS = -no-undefined -version-info 0:0:0
endif
diff --git a/configure.ac b/configure.ac
index c1314bb..7a2795f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,7 @@ AC_SUBST([SRD_PKGLIBS])
# Retrieve the compile and link flags for all modules combined.
# Also, bail out at this point if any module dependency is not met.
PKG_CHECK_MODULES([LIBSIGROKDECODE], [glib-2.0 >= 2.34 $SRD_PKGLIBS])
+PKG_CHECK_MODULES([LIBIRMP], [glib-2.0 >= 2.34 $SRD_PKGLIBS])
PKG_CHECK_MODULES([TESTS], [$SRD_PKGLIBS_TESTS glib-2.0 $SRD_PKGLIBS])
srd_glib_version=`$PKG_CONFIG --modversion glib-2.0 2>&AS_MESSAGE_LOG_FD`
diff --git a/irmp/irmp-main-sharedlib.c b/irmp/irmp-main-sharedlib.c
index cbf239a..4d02460 100644
--- a/irmp/irmp-main-sharedlib.c
+++ b/irmp/irmp-main-sharedlib.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2009-2019 Frank Meyer - frank(at)fli4l.de
* Copyright (c) 2009-2019 René Staffen - r.staffen(at)gmx.de
+ * Copyright (c) 2020-2021 Gerhard Sittig <gerhard.sittig@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,6 +17,9 @@
*/
#include "irmp-main-sharedlib.h"
+#include <errno.h>
+#include <glib.h>
+#include <Python.h>
#include <stdlib.h>
#include <string.h>
@@ -98,6 +102,109 @@
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
+static int irmp_lib_initialized;
+static size_t irmp_lib_client_id;
+static GMutex irmp_lib_mutex;
+
+struct irmp_instance {
+ size_t client_id;
+ GMutex *mutex;
+};
+
+static void irmp_lib_autoinit(void)
+{
+ if (irmp_lib_initialized)
+ return;
+
+ irmp_lib_client_id = 0;
+ g_mutex_init(&irmp_lib_mutex);
+
+ irmp_lib_initialized = 1;
+}
+
+static size_t irmp_next_client_id(void)
+{
+ size_t id;
+
+ do {
+ id = ++irmp_lib_client_id;
+ } while (!id);
+
+ return id;
+}
+
+IRMP_DLLEXPORT struct irmp_instance *irmp_instance_alloc(void)
+{
+ struct irmp_instance *inst;
+
+ irmp_lib_autoinit();
+
+ inst = g_malloc0(sizeof(*inst));
+ if (!inst)
+ return NULL;
+
+ inst->client_id = irmp_next_client_id();
+ inst->mutex = &irmp_lib_mutex;
+
+ return inst;
+}
+
+IRMP_DLLEXPORT void irmp_instance_free(struct irmp_instance *state)
+{
+
+ irmp_lib_autoinit();
+
+ if (!state)
+ return;
+
+ g_free(state);
+}
+
+IRMP_DLLEXPORT size_t irmp_instance_id(struct irmp_instance *state)
+{
+
+ irmp_lib_autoinit();
+
+ return state ? state->client_id : 0;
+}
+
+IRMP_DLLEXPORT int irmp_instance_lock(struct irmp_instance *state, int wait)
+{
+ int rc;
+ PyGILState_STATE pyst;
+
+ irmp_lib_autoinit();
+
+ if (!state || !state->mutex)
+ return -EINVAL;
+
+ pyst = PyGILState_Ensure();
+ Py_BEGIN_ALLOW_THREADS
+ if (wait) {
+ g_mutex_lock(state->mutex);
+ rc = 0;
+ } else {
+ rc = g_mutex_trylock(state->mutex);
+ }
+ Py_END_ALLOW_THREADS
+ PyGILState_Release(pyst);
+ if (rc != 0)
+ return rc;
+
+ return 0;
+}
+
+IRMP_DLLEXPORT void irmp_instance_unlock(struct irmp_instance *state)
+{
+
+ irmp_lib_autoinit();
+
+ if (!state || !state->mutex)
+ return;
+
+ g_mutex_unlock(state->mutex);
+}
+
static uint32_t s_end_sample;
IRMP_DLLEXPORT uint32_t irmp_get_sample_rate(void)
@@ -195,3 +302,8 @@ IRMP_DLLEXPORT const char *irmp_get_protocol_name(uint32_t protocol)
return "unknown";
return name;
}
+
+static __attribute__((constructor)) void init(void)
+{
+ irmp_lib_autoinit();
+}
diff --git a/irmp/irmp-main-sharedlib.h b/irmp/irmp-main-sharedlib.h
index 94065f3..67e7997 100644
--- a/irmp/irmp-main-sharedlib.h
+++ b/irmp/irmp-main-sharedlib.h
@@ -3,6 +3,7 @@
*
* Copyright (c) 2009-2019 Frank Meyer - frank(at)fli4l.de
* Copyright (c) 2009-2019 René Staffen - r.staffen(at)gmx.de
+ * Copyright (c) 2020-2021 Gerhard Sittig <gerhard.sittig@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,6 +34,49 @@ extern "C" {
#define WITH_IRMP_DETECT_BUFFER 0
/**
+ * @brief State container for a decoder core instance. Opaque to clients.
+ */
+struct irmp_instance;
+
+/**
+ * @brief Allocate a decoder instance.
+ *
+ * @returns Reference to the allocated instance state.
+ */
+IRMP_DLLEXPORT struct irmp_instance *irmp_instance_alloc(void);
+
+/**
+ * @brief Release a decoder instance.
+ *
+ * @param[in] state Reference to the instance's state.
+ */
+IRMP_DLLEXPORT void irmp_instance_free(struct irmp_instance *state);
+
+/**
+ * @brief Get the client ID of an IRMP decoder core instance.
+ */
+IRMP_DLLEXPORT size_t irmp_instance_id(struct irmp_instance *state);
+
+/**
+ * @brief Acquire a decoder instance's lock.
+ *
+ * @param[in] state Reference to the instance's state.
+ * @param[in] wait Whether to block until the lock is acquired.
+ *
+ * @returns 0 upon success, non-zero upon failure
+ */
+IRMP_DLLEXPORT int irmp_instance_lock(struct irmp_instance *state, int wait);
+
+/**
+ * @brief Release a decoder instance's lock.
+ *
+ * @param[in] state Reference to the instance's state.
+ *
+ * @returns 0 upon success, non-zero upon failure
+ */
+IRMP_DLLEXPORT void irmp_instance_unlock(struct irmp_instance *state);
+
+/**
* @brief IR decoder result data at the library's public API.
*/
struct irmp_result_data {