From ddfbaea04ac415ce036350e3f2244b6f6bb881dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Thu, 3 Jun 2010 23:55:27 +0300 Subject: [PATCH] Protect XInitThreads() with a global lock --- include/vlc_threads.h | 2 ++ include/vlc_xlib.h | 41 ++++++++++++++++++++++++++ modules/audio_output/pulse.c | 12 ++++---- modules/codec/avcodec/vaapi.c | 7 ++++- modules/gui/hildon/maemo.c | 3 +- modules/gui/qt4/qt4.cpp | 4 +-- modules/gui/skins2/x11/x11_factory.cpp | 3 +- modules/video_output/xcb/glx.c | 3 +- src/Makefile.am | 1 + src/misc/threads.c | 1 + 10 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 include/vlc_xlib.h diff --git a/include/vlc_threads.h b/include/vlc_threads.h index 5d9ab65cb2..3770e2fa0f 100644 --- a/include/vlc_threads.h +++ b/include/vlc_threads.h @@ -445,6 +445,8 @@ class vlc_mutex_locker enum { VLC_AVCODEC_MUTEX = 0, VLC_GCRYPT_MUTEX, + VLC_XLIB_MUTEX, + /* Insert new entry HERE */ VLC_MAX_MUTEX }; diff --git a/include/vlc_xlib.h b/include/vlc_xlib.h new file mode 100644 index 0000000000..4e3632c341 --- /dev/null +++ b/include/vlc_xlib.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * vlc_xlib.h: initialization of Xlib + ***************************************************************************** + * Copyright (C) 2010 RĂ©mi Denis-Courmont + * + * 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 + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + *****************************************************************************/ + +#ifndef VLC_XLIB_H +# define VLC_XLIB_H 1 + +# include + +static inline bool vlc_xlib_init (vlc_object_t *obj) +{ + bool ok = false; + + if (var_InheritBool (obj, "xlib")) + { + /* XInitThreads() can be called multiple times, + * but it is not reentrant. */ + vlc_global_lock (VLC_XLIB_MUTEX); + ok = XInitThreads () != 0; + vlc_global_unlock (VLC_XLIB_MUTEX); + } + return ok; +} + +#endif diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c index a064ff3aec..e7c74508dc 100644 --- a/modules/audio_output/pulse.c +++ b/modules/audio_output/pulse.c @@ -34,9 +34,10 @@ #include #include -#ifdef HAVE_X11_XLIB_H -# include +#ifdef X_DISPLAY_MISSING +# error Xlib required due to PulseAudio bug 799! #endif +#include #include @@ -121,12 +122,9 @@ static int Open ( vlc_object_t *p_this ) struct pa_buffer_attr a; struct pa_channel_map map; -#ifdef X_DISPLAY_MISSING -# error Xlib required due to PulseAudio bug 799! -#else - if( !var_InheritBool( p_this, "xlib" ) || !XInitThreads() ) + if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; -#endif + /* Allocate structures */ p_aout->output.p_sys = p_sys = calloc( 1, sizeof( aout_sys_t ) ); if( p_sys == NULL ) diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c index de793acaa1..5f676d870d 100644 --- a/modules/codec/avcodec/vaapi.c +++ b/modules/codec/avcodec/vaapi.c @@ -464,7 +464,12 @@ static void Delete( vlc_va_t *p_external ) /* */ vlc_va_t *vlc_va_NewVaapi( int i_codec_id ) { - if( !XInitThreads() ) + bool fail; + + vlc_global_lock( VLC_XLIB_MUTEX ); + fail = !XInitThreads(); + vlc_global_unlock( VLC_XLIB_MUTEX ) + if( unlikely(fail) ) return NULL; vlc_va_vaapi_t *p_va = calloc( 1, sizeof(*p_va) ); diff --git a/modules/gui/hildon/maemo.c b/modules/gui/hildon/maemo.c index 640069d55e..401860f845 100644 --- a/modules/gui/hildon/maemo.c +++ b/modules/gui/hildon/maemo.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,7 @@ static int Open( vlc_object_t *p_this ) intf_sys_t *p_sys; vlc_value_t val; - if( !var_InheritBool( p_this, "xlib" ) || !XInitThreads() ) + if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; /* Allocate instance and initialize some members */ diff --git a/modules/gui/qt4/qt4.cpp b/modules/gui/qt4/qt4.cpp index 6d13f5bcec..daa7b5fe5e 100644 --- a/modules/gui/qt4/qt4.cpp +++ b/modules/gui/qt4/qt4.cpp @@ -39,7 +39,7 @@ #include "util/qvlcapp.hpp" /* QVLCApplication definition */ #ifdef Q_WS_X11 - #include + #include #endif #include "../../../share/vlc32x32.xpm" @@ -283,7 +283,7 @@ static int Open( vlc_object_t *p_this, bool isDialogProvider ) intf_thread_t *p_intf = (intf_thread_t *)p_this; #ifdef Q_WS_X11 - if( !var_InheritBool( p_this, "xlib" ) || !XInitThreads() ) + if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; char *display = var_CreateGetNonEmptyString( p_intf, "x11-display" ); diff --git a/modules/gui/skins2/x11/x11_factory.cpp b/modules/gui/skins2/x11/x11_factory.cpp index 5d09402ba9..22c329b4ca 100644 --- a/modules/gui/skins2/x11/x11_factory.cpp +++ b/modules/gui/skins2/x11/x11_factory.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "x11_factory.hpp" #include "x11_display.hpp" @@ -57,7 +58,7 @@ X11Factory::~X11Factory() bool X11Factory::init() { // make sure xlib is safe-thread - if( !var_InheritBool( getIntf(), "xlib" ) || !XInitThreads() ) + if( !vlc_xlib_init( getIntf() ) ) { msg_Err( getIntf(), "initializing xlib for multi-threading failed" ); return false; diff --git a/modules/video_output/xcb/glx.c b/modules/video_output/xcb/glx.c index 7598cd10f3..7d148f1932 100644 --- a/modules/video_output/xcb/glx.c +++ b/modules/video_output/xcb/glx.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include "../opengl.h" @@ -203,7 +204,7 @@ static int CreateWindow (vout_display_t *vd, xcb_connection_t *conn, */ static int Open (vlc_object_t *obj) { - if (!var_InheritBool (obj, "xlib") || !XInitThreads ()) + if (!vlc_xlib_init (obj)) return VLC_EGENERIC; vout_display_t *vd = (vout_display_t *)obj; diff --git a/src/Makefile.am b/src/Makefile.am index 9bc9f31786..68aaf26c2e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -107,6 +107,7 @@ pluginsinclude_HEADERS = \ ../include/vlc_vout_osd.h \ ../include/vlc_vout_window.h \ ../include/vlc_xml.h \ + ../include/vlc_xlib.h \ $(NULL) noinst_HEADERS = \ diff --git a/src/misc/threads.c b/src/misc/threads.c index ba93c1bb27..fd84ad7270 100644 --- a/src/misc/threads.c +++ b/src/misc/threads.c @@ -241,6 +241,7 @@ void vlc_global_mutex (unsigned n, bool acquire) static vlc_mutex_t locks[] = { VLC_STATIC_MUTEX, VLC_STATIC_MUTEX, + VLC_STATIC_MUTEX, }; assert (n < (sizeof (locks) / sizeof (locks[0]))); vlc_mutex_t *lock = locks + n;