[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