summaryrefslogtreecommitdiff
path: root/irmp
diff options
context:
space:
mode:
Diffstat (limited to 'irmp')
-rw-r--r--irmp/irmp-main-sharedlib.c112
-rw-r--r--irmp/irmp-main-sharedlib.h44
2 files changed, 156 insertions, 0 deletions
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 {