[vlc-devel] [PATCH] libvlc: add internal function libvlc_get_thread_context()
Jerome Forissier
jerome at taodyne.com
Thu Feb 27 19:07:44 CET 2014
This commit rewrites the error handling functions (libvlc_errmsg() et al.)
so that they use a common per-thread structure. Should other parts of the
library need to store per-thread data in the future, no additional
vlc_threadvar_t will be required.
---
lib/Makefile.am | 1 +
lib/context.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/error.c | 40 +++++++++++---------------------
lib/libvlc_internal.h | 8 +++++++
4 files changed, 86 insertions(+), 27 deletions(-)
create mode 100644 lib/context.c
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0e38646..6f782d3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -36,6 +36,7 @@ libvlc_la_SOURCES = \
media_internal.h \
media_list_internal.h \
media_player_internal.h \
+ context.c \
core.c \
error.c \
log.c \
diff --git a/lib/context.c b/lib/context.c
new file mode 100644
index 0000000..a14541c
--- /dev/null
+++ b/lib/context.c
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * context.c: Hold per-thread data for libvlc
+ *****************************************************************************
+ * Copyright (C) 2014 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "libvlc_internal.h"
+
+#include <assert.h>
+#include <vlc/libvlc.h>
+
+
+static vlc_threadvar_t context;
+
+static vlc_mutex_t lock = VLC_STATIC_MUTEX;
+static uintptr_t refs = 0;
+
+static void free_context(void *ptr)
+{
+ libvlc_thread_context_t *ctx = (libvlc_thread_context_t *)ptr;
+ if (ctx->err.free)
+ ctx->err.free(ctx->err.msg);
+ free(ctx);
+}
+
+void libvlc_threads_init (void)
+{
+ vlc_mutex_lock (&lock);
+ if (refs++ == 0)
+ vlc_threadvar_create (&context, free_context);
+ vlc_mutex_unlock (&lock);
+ libvlc_thread_context_t *ctx =
+ (libvlc_thread_context_t *)calloc (1, sizeof(*ctx));
+ vlc_threadvar_set (context, ctx);
+}
+
+void libvlc_threads_deinit (void)
+{
+ vlc_mutex_lock (&lock);
+ assert (refs > 0);
+ if (--refs == 0)
+ vlc_threadvar_delete (&context);
+ vlc_mutex_unlock (&lock);
+}
+
+libvlc_thread_context_t *libvlc_get_thread_context (void)
+{
+ return (libvlc_thread_context_t *) vlc_threadvar_get (context);
+}
+
diff --git a/lib/error.c b/lib/error.c
index 45397a6..c7af88a 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -27,38 +27,25 @@
static const char oom[] = "Out of memory";
-/* TODO: use only one thread-specific key for whole libvlc */
-static vlc_threadvar_t context;
-static vlc_mutex_t lock = VLC_STATIC_MUTEX;
-static uintptr_t refs = 0;
-
-static void free_msg (void *msg)
-{
- if (msg != oom)
- free (msg);
-}
-
-void libvlc_threads_init (void)
+static char *get_error (void)
{
- vlc_mutex_lock (&lock);
- if (refs++ == 0)
- vlc_threadvar_create (&context, free_msg);
- vlc_mutex_unlock (&lock);
+ libvlc_thread_context_t *ctx = libvlc_get_thread_context ();
+ return ctx->err.msg;
}
-void libvlc_threads_deinit (void)
+static void free_msg (void *msg)
{
- vlc_mutex_lock (&lock);
- assert (refs > 0);
- if (--refs == 0)
- vlc_threadvar_delete (&context);
- vlc_mutex_unlock (&lock);
+ if (msg != oom)
+ free(msg);
}
-static char *get_error (void)
+static set_error (char *msg)
{
- return vlc_threadvar_get (context);
+ libvlc_thread_context_t *ctx = libvlc_get_thread_context ();
+ if (!ctx->err.free)
+ ctx->err.free = free_msg;
+ ctx->err.msg = msg;
}
static void free_error (void)
@@ -86,7 +73,7 @@ const char *libvlc_errmsg (void)
void libvlc_clearerr (void)
{
free_error ();
- vlc_threadvar_set (context, NULL);
+ set_error (NULL);
}
/**
@@ -103,7 +90,7 @@ const char *libvlc_vprinterr (const char *fmt, va_list ap)
msg = (char *)oom;
free_error ();
- vlc_threadvar_set (context, msg);
+ set_error (msg);
return msg;
}
@@ -122,4 +109,3 @@ const char *libvlc_printerr (const char *fmt, ...)
va_end (ap);
return msg;
}
-
diff --git a/lib/libvlc_internal.h b/lib/libvlc_internal.h
index 64585a7..7690bae 100644
--- a/lib/libvlc_internal.h
+++ b/lib/libvlc_internal.h
@@ -86,10 +86,18 @@ struct libvlc_instance_t
***************************************************************************/
/* Thread context */
+typedef struct libvlc_thread_context_t
+{
+ struct {
+ char *msg;
+ void (*free) (void *);
+ } err;
+} libvlc_thread_context_t;
void libvlc_threads_init (void);
void libvlc_threads_deinit (void);
void libvlc_log_init (void);
void libvlc_log_deinit (void);
+libvlc_thread_context_t * libvlc_get_thread_context(void);
/* Events */
libvlc_event_manager_t * libvlc_event_manager_new(
--
1.8.1.5
More information about the vlc-devel
mailing list