From 89987e1109b96f81396b9248490b6aed717d7804 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 4 Oct 2002 18:07:22 +0000 Subject: [PATCH] * ./configure.ac.in: removed now unnecessary --force-exe-suffix flag. * ./src/misc/objects.c: structure_lock is now local. * ./src/misc/threads.c: implemented named mutexes which provide a handy way to protect data across plugins which might be sharing the same resources. Thread-unsafe libraries come to mind, but we can imagine using a named mutex for configuration files, or special devices. * ./include/main.h: removed global_lock because of vlc_mutex_need, removed p_global_data because it was never used, removed structure_lock because it did not belong here. --- configure.ac.in | 2 +- include/main.h | 9 +-- include/vlc_threads_funcs.h | 17 ++++- modules/access/vcd/vcd.c | 4 +- modules/audio_output/arts.c | 4 +- modules/gui/gtk/gtk.c | 6 +- modules/misc/gtk_main.c | 23 ++++--- modules/video_output/qte/qte.cpp | 20 +++--- src/audio_output/input.c | 3 +- src/libvlc.c | 23 ++++--- src/misc/objects.c | 85 +++++++++++++---------- src/misc/threads.c | 115 ++++++++++++++++++++++++++++++- 12 files changed, 222 insertions(+), 89 deletions(-) diff --git a/configure.ac.in b/configure.ac.in index ad31ad25f9..d9ffb22ef3 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -99,7 +99,7 @@ case "x${target_os}" in SYS=mingw32 AC_CHECK_TOOL(WINDRES, windres, :) CPPFLAGS_save="${CPPFLAGS_save} -D_OFF_T_ -D_off_t=long"; CPPFLAGS="${CPPFLAGS_save}" - LDFLAGS_vlc="${LDFLAGS_vlc} -lws2_32 -lnetapi32 -mwindows -Xlinker --force-exe-suffix" + LDFLAGS_vlc="${LDFLAGS_vlc} -lws2_32 -lnetapi32 -mwindows" LDFLAGS_ipv4="${LDFLAGS_ipv4} -lws2_32" LDFLAGS_ipv6="${LDFLAGS_ipv6} -lws2_32" LDFLAGS_access_http="${LDFLAGS_http} -lws2_32" diff --git a/include/main.h b/include/main.h index 1f76970fae..2fc5078b7f 100644 --- a/include/main.h +++ b/include/main.h @@ -3,7 +3,7 @@ * Declaration and extern access to global program object. ***************************************************************************** * Copyright (C) 1999, 2000, 2001, 2002 VideoLAN - * $Id: main.h,v 1.47 2002/10/03 18:56:09 sam Exp $ + * $Id: main.h,v 1.48 2002/10/04 18:07:21 sam Exp $ * * Authors: Vincent Seguin * @@ -48,13 +48,6 @@ struct libvlc_t int i_objects; /* Attached objects count */ vlc_object_t ** pp_objects; /* Array of all objects */ - /* The big, evil global lock */ - vlc_mutex_t global_lock; - void * p_global_data; - - /* Locks */ - vlc_mutex_t structure_lock; /* lock for the p_vlc tree */ - /* The message bank */ msg_bank_t msg_bank; diff --git a/include/vlc_threads_funcs.h b/include/vlc_threads_funcs.h index d9586bde59..d813a1c314 100644 --- a/include/vlc_threads_funcs.h +++ b/include/vlc_threads_funcs.h @@ -3,7 +3,7 @@ * This header provides a portable threads implementation. ***************************************************************************** * Copyright (C) 1999, 2002 VideoLAN - * $Id: vlc_threads_funcs.h,v 1.4 2002/10/03 17:01:59 gbazin Exp $ + * $Id: vlc_threads_funcs.h,v 1.5 2002/10/04 18:07:21 sam Exp $ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -38,6 +38,9 @@ VLC_EXPORT( int, __vlc_thread_create, ( vlc_object_t *, char *, int, char *, vo VLC_EXPORT( void, __vlc_thread_ready, ( vlc_object_t * ) ); VLC_EXPORT( void, __vlc_thread_join, ( vlc_object_t *, char *, int ) ); +VLC_EXPORT( vlc_mutex_t *, __vlc_mutex_need, ( vlc_object_t *, char * ) ); +VLC_EXPORT( void , __vlc_mutex_unneed, ( vlc_object_t *, char * ) ); + /***************************************************************************** * vlc_threads_init: initialize threads system *****************************************************************************/ @@ -56,6 +59,12 @@ VLC_EXPORT( void, __vlc_thread_join, ( vlc_object_t *, char *, int ) ); #define vlc_mutex_init( P_THIS, P_MUTEX ) \ __vlc_mutex_init( VLC_OBJECT(P_THIS), P_MUTEX ) +/***************************************************************************** + * vlc_mutex_need: create a global mutex from its name + *****************************************************************************/ +#define vlc_mutex_need( P_THIS, P_NAME ) \ + __vlc_mutex_need( VLC_OBJECT(P_THIS), P_NAME ) + /***************************************************************************** * vlc_mutex_lock: lock a mutex *****************************************************************************/ @@ -192,6 +201,12 @@ static inline int __vlc_mutex_unlock( char * psz_file, int i_line, return i_result; } +/***************************************************************************** + * vlc_mutex_unneed: destroycreate a global mutex from its name + *****************************************************************************/ +#define vlc_mutex_unneed( P_THIS, P_NAME ) \ + __vlc_mutex_unneed( VLC_OBJECT(P_THIS), P_NAME ) + /***************************************************************************** * vlc_mutex_destroy: destroy a mutex *****************************************************************************/ diff --git a/modules/access/vcd/vcd.c b/modules/access/vcd/vcd.c index 07956c8152..b03b259278 100644 --- a/modules/access/vcd/vcd.c +++ b/modules/access/vcd/vcd.c @@ -2,7 +2,7 @@ * vcd.c : VCD input module for vlc ***************************************************************************** * Copyright (C) 2000 VideoLAN - * $Id: vcd.c,v 1.5 2002/08/29 23:53:22 massiot Exp $ + * $Id: vcd.c,v 1.6 2002/10/04 18:07:21 sam Exp $ * * Author: Johan Bilien * @@ -181,7 +181,7 @@ static int VCDOpen( vlc_object_t *p_this ) if( p_vcd->i_handle == -1 ) { - msg_Err( p_input, "could not open %s\n", psz_source ); + msg_Err( p_input, "could not open %s", psz_source ); free (p_vcd); return -1; } diff --git a/modules/audio_output/arts.c b/modules/audio_output/arts.c index f8539a0c2e..e24c08a955 100644 --- a/modules/audio_output/arts.c +++ b/modules/audio_output/arts.c @@ -2,7 +2,7 @@ * arts.c : aRts module ***************************************************************************** * Copyright (C) 2001-2002 VideoLAN - * $Id: arts.c,v 1.12 2002/09/30 11:05:35 sam Exp $ + * $Id: arts.c,v 1.13 2002/10/04 18:07:21 sam Exp $ * * Authors: Emmanuel Blindauer * Samuel Hocevar @@ -123,7 +123,7 @@ static int Open( vlc_object_t *p_this ) * (mtime_t)arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY ); p_sys->i_size = arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE ); - msg_Dbg( p_aout, "aRts initialized, latency %i000, %i packets of size %i\n", + msg_Dbg( p_aout, "aRts initialized, latency %i000, %i packets of size %i", arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY ), arts_stream_get( p_sys->stream, ARTS_P_PACKET_COUNT ), arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE ) ); diff --git a/modules/gui/gtk/gtk.c b/modules/gui/gtk/gtk.c index 6104b2be6e..d187651bcc 100644 --- a/modules/gui/gtk/gtk.c +++ b/modules/gui/gtk/gtk.c @@ -2,7 +2,7 @@ * gtk.c : Gtk+ plugin for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: gtk.c,v 1.4 2002/10/04 12:01:40 gbazin Exp $ + * $Id: gtk.c,v 1.5 2002/10/04 18:07:21 sam Exp $ * * Authors: Samuel Hocevar * @@ -171,11 +171,7 @@ static void Run( intf_thread_t *p_intf ) int i_args = 1; int i_dummy; - /* gtk_init will register stuff with g_atexit, so we need to take - * the global lock if we want to be able to intercept the calls */ - vlc_mutex_lock( &p_intf->p_libvlc->global_lock ); gtk_init( &i_args, &pp_args ); - vlc_mutex_unlock( &p_intf->p_libvlc->global_lock ); #endif /* Create some useful widgets that will certainly be used */ diff --git a/modules/misc/gtk_main.c b/modules/misc/gtk_main.c index 0f5f2c875a..799cf7dd0a 100644 --- a/modules/misc/gtk_main.c +++ b/modules/misc/gtk_main.c @@ -2,7 +2,7 @@ * gtk_main.c : Gtk+ wrapper for gtk_main ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: gtk_main.c,v 1.8 2002/10/04 13:13:54 sam Exp $ + * $Id: gtk_main.c,v 1.9 2002/10/04 18:07:21 sam Exp $ * * Authors: Samuel Hocevar * @@ -56,6 +56,7 @@ typedef struct gtk_main_t /***************************************************************************** * Local variables (mutex-protected). *****************************************************************************/ +static vlc_mutex_t * p_gtklock; static int i_refcount = 0; static gtk_main_t * p_gtk_main = NULL; @@ -80,12 +81,15 @@ vlc_module_end(); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - vlc_mutex_lock( &p_this->p_libvlc->global_lock ); + /* FIXME: put this in the module (de)initialization ASAP */ + p_gtklock = vlc_mutex_need( p_this, "gtk" ); + + vlc_mutex_lock( p_gtklock ); if( i_refcount > 0 ) { i_refcount++; - vlc_mutex_unlock( &p_this->p_libvlc->global_lock ); + vlc_mutex_unlock( p_gtklock ); return VLC_SUCCESS; } @@ -105,12 +109,13 @@ static int Open( vlc_object_t *p_this ) { vlc_object_destroy( p_gtk_main ); i_refcount--; - vlc_mutex_unlock( &p_this->p_libvlc->global_lock ); + vlc_mutex_unlock( p_gtklock ); + vlc_mutex_unneed( p_this, "gtk" ); return VLC_ETHREAD; } i_refcount++; - vlc_mutex_unlock( &p_this->p_libvlc->global_lock ); + vlc_mutex_unlock( p_gtklock ); return VLC_SUCCESS; } @@ -120,13 +125,14 @@ static int Open( vlc_object_t *p_this ) *****************************************************************************/ static void Close( vlc_object_t *p_this ) { - vlc_mutex_lock( &p_this->p_libvlc->global_lock ); + vlc_mutex_lock( p_gtklock ); i_refcount--; if( i_refcount > 0 ) { - vlc_mutex_unlock( &p_this->p_libvlc->global_lock ); + vlc_mutex_unlock( p_gtklock ); + vlc_mutex_unneed( p_this, "gtk" ); return; } @@ -136,7 +142,8 @@ static void Close( vlc_object_t *p_this ) vlc_object_destroy( p_gtk_main ); p_gtk_main = NULL; - vlc_mutex_unlock( &p_this->p_libvlc->global_lock ); + vlc_mutex_unlock( p_gtklock ); + vlc_mutex_unneed( p_this, "gtk" ); } static gint foo( gpointer bar ) { return TRUE; } diff --git a/modules/video_output/qte/qte.cpp b/modules/video_output/qte/qte.cpp index aeb3584236..294d456f6e 100644 --- a/modules/video_output/qte/qte.cpp +++ b/modules/video_output/qte/qte.cpp @@ -2,7 +2,7 @@ * qte.cpp : QT Embedded plugin for vlc ***************************************************************************** * Copyright (C) 1998-2002 VideoLAN - * $Id: qte.cpp,v 1.3 2002/09/23 21:44:23 jpsaman Exp $ + * $Id: qte.cpp,v 1.4 2002/10/04 18:07:21 sam Exp $ * * Authors: Gerald Hansink * Jean-Paul Saman @@ -160,7 +160,7 @@ static int Open( vlc_object_t *p_this ) CreateQtWindow(p_vout); - //msg_Err(p_vout, "-vout_Create::qte\n" ); + //msg_Err(p_vout, "-vout_Create::qte" ); return( 0 ); } @@ -173,7 +173,7 @@ static void Close ( vlc_object_t *p_this ) { vout_thread_t * p_vout = (vout_thread_t *)p_this; - //msg_Err( p_vout, "+vout_Destroy::qte\n" ); + //msg_Err( p_vout, "+vout_Destroy::qte" ); DestroyQtWindow(p_vout); free(p_vout->p_sys); } @@ -191,7 +191,7 @@ static int Init( vout_thread_t *p_vout ) int dd = QPixmap::defaultDepth(); - //msg_Err( p_vout,"+vout_Init::qte\n" ); + //msg_Err( p_vout,"+vout_Init::qte" ); I_OUTPUTPICTURES = 0; @@ -234,7 +234,7 @@ static int Init( vout_thread_t *p_vout ) I_OUTPUTPICTURES++; } - //msg_Err(p_vout, "-vout_Init::qte %d output pictures\n", I_OUTPUTPICTURES); + //msg_Err(p_vout, "-vout_Init::qte %d output pictures", I_OUTPUTPICTURES); return( 0 ); } @@ -245,7 +245,7 @@ static int Init( vout_thread_t *p_vout ) *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { - //msg_Err(p_vout, "+vout_Render::qte\n" ); + //msg_Err(p_vout, "+vout_Render::qte" ); ; } @@ -319,7 +319,7 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic ) *****************************************************************************/ static int Manage( vout_thread_t *p_vout ) { - //msg_Err(p_vout, "+vout_Manage::qte\n" ); + //msg_Err(p_vout, "+vout_Manage::qte" ); return 0; } @@ -333,7 +333,7 @@ static void End( vout_thread_t *p_vout ) { int i_index; - //msg_Err(p_vout, "+vout_End::qte\n" ); + //msg_Err(p_vout, "+vout_End::qte" ); /* Free the direct buffers we allocated */ for( i_index = I_OUTPUTPICTURES ; i_index ; ) @@ -353,7 +353,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) { int dd = QPixmap::defaultDepth(); - //msg_Err(p_vout, "+NewPicture::dd = %d\n",dd ); + //msg_Err(p_vout, "+NewPicture::dd = %d",dd ); p_pic->p_sys = (picture_sys_t*) malloc( sizeof( picture_sys_t ) ); @@ -428,7 +428,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) } /* - msg_Err(p_vout, "NewPicture: %d %d %d\n",p_vout->output.i_width, + msg_Err(p_vout, "NewPicture: %d %d %d",p_vout->output.i_width, p_vout->output.i_height, p_vout->output.i_chroma ); */ diff --git a/src/audio_output/input.c b/src/audio_output/input.c index b40367b0ea..9cf9eda250 100644 --- a/src/audio_output/input.c +++ b/src/audio_output/input.c @@ -2,7 +2,7 @@ * input.c : internal management of input streams for the audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: input.c,v 1.14 2002/09/27 23:38:04 massiot Exp $ + * $Id: input.c,v 1.15 2002/10/04 18:07:22 sam Exp $ * * Authors: Christophe Massiot * @@ -168,7 +168,6 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, mdate() - p_buffer->start_date ); aout_BufferFree( p_buffer ); - vlc_mutex_unlock( &p_input->lock ); return 0; } diff --git a/src/libvlc.c b/src/libvlc.c index 3c8f3c9b29..df45694bbd 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -2,7 +2,7 @@ * libvlc.c: main libvlc source ***************************************************************************** * Copyright (C) 1998-2002 VideoLAN - * $Id: libvlc.c,v 1.35 2002/10/03 18:56:09 sam Exp $ + * $Id: libvlc.c,v 1.36 2002/10/04 18:07:22 sam Exp $ * * Authors: Vincent Seguin * Samuel Hocevar @@ -142,6 +142,7 @@ vlc_t * vlc_create_r( void ) { int i_ret; vlc_t * p_vlc = NULL; + vlc_mutex_t * p_libvlc_lock; /* vlc_threads_init *must* be the first internal call! No other call is * allowed before the thread system has been initialized. */ @@ -152,16 +153,13 @@ vlc_t * vlc_create_r( void ) } /* Now that the thread system is initialized, we don't have much, but - * at least we have libvlc.global_lock */ - vlc_mutex_lock( &libvlc.global_lock ); + * at least we have vlc_mutex_need */ + p_libvlc_lock = vlc_mutex_need( &libvlc, "libvlc" ); + vlc_mutex_lock( p_libvlc_lock ); if( !libvlc.b_ready ) { char *psz_env; - vlc_mutex_init( &libvlc, &libvlc.structure_lock ); - libvlc.p_global_data = NULL; - libvlc.b_ready = VLC_TRUE; - /* Guess what CPU we have */ libvlc.i_cpu = CPUCapabilities(); @@ -182,14 +180,17 @@ vlc_t * vlc_create_r( void ) msg_Dbg( &libvlc, COPYRIGHT_MESSAGE ); msg_Dbg( &libvlc, "libvlc was configured with %s", CONFIGURE_LINE ); - /* Initialize the module bank and and load the configuration of the + /* Initialize the module bank and load the configuration of the * main module. We need to do this at this stage to be able to display * a short help if required by the user. (short help == main module * options) */ module_InitBank( &libvlc ); module_LoadMain( &libvlc ); + + libvlc.b_ready = VLC_TRUE; } - vlc_mutex_unlock( &libvlc.global_lock ); + vlc_mutex_unlock( p_libvlc_lock ); + vlc_mutex_unneed( &libvlc, "libvlc" ); /* Allocate a vlc object */ p_vlc = vlc_object_create( &libvlc, VLC_OBJECT_VLC ); @@ -416,9 +417,9 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] ) else { int i_tmp = config_GetInt( p_vlc, "verbose" ); - if( i_tmp >= 0 && i_tmp <= 4 ) + if( i_tmp >= 0 ) { - libvlc.i_verbose = i_tmp; + libvlc.i_verbose = __MIN( i_tmp, 4 ); } } libvlc.b_color = libvlc.b_color || config_GetInt( p_vlc, "color" ); diff --git a/src/misc/objects.c b/src/misc/objects.c index 857d43b4f8..5a1adbd911 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -2,7 +2,7 @@ * objects.c: vlc_object_t handling ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: objects.c,v 1.22 2002/10/03 18:56:10 sam Exp $ + * $Id: objects.c,v 1.23 2002/10/04 18:07:22 sam Exp $ * * Authors: Samuel Hocevar * @@ -56,6 +56,11 @@ static void SetAttachment ( vlc_object_t *, vlc_bool_t ); static vlc_list_t * NewList ( void ); static vlc_list_t * ListAppend ( vlc_list_t *, vlc_object_t * ); +/***************************************************************************** + * Local structure lock + *****************************************************************************/ +static vlc_mutex_t structure_lock; + /***************************************************************************** * vlc_object_create: initialize a vlc object ***************************************************************************** @@ -142,10 +147,9 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) p_new->b_dead = VLC_FALSE; p_new->b_attached = VLC_FALSE; - /* If i_type is root, then p_new is our own p_libvlc */ if( i_type == VLC_OBJECT_ROOT ) { - /* We are the first object ... no need to lock. */ + /* If i_type is root, then p_new is actually p_libvlc */ p_new->p_libvlc = (libvlc_t*)p_new; p_new->p_vlc = NULL; @@ -163,7 +167,7 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) p_new->p_vlc = ( i_type == VLC_OBJECT_VLC ) ? (vlc_t*)p_new : p_this->p_vlc; - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); p_new->p_libvlc->i_counter++; p_new->i_object_id = p_new->p_libvlc->i_counter; @@ -176,7 +180,7 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) p_new->p_libvlc->i_objects * sizeof(vlc_object_t *) ); p_new->p_libvlc->pp_objects[ p_new->p_libvlc->i_objects - 1 ] = p_new; - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } p_new->p_parent = NULL; @@ -185,9 +189,15 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) p_new->p_private = NULL; + /* Initialize mutexes and condvars */ vlc_mutex_init( p_new, &p_new->object_lock ); vlc_cond_init( p_new, &p_new->object_wait ); + if( i_type == VLC_OBJECT_ROOT ) + { + vlc_mutex_init( p_new, &structure_lock ); + } + return p_new; } @@ -240,14 +250,22 @@ void __vlc_object_destroy( vlc_object_t *p_this ) msleep( 100000 ); } - /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's - * useless to try and recover anything if pp_objects gets smashed. */ - if( p_this->i_object_type != VLC_OBJECT_ROOT ) + if( p_this->i_object_type == VLC_OBJECT_ROOT ) + { + /* We are the root object ... no need to lock. */ + free( p_this->p_libvlc->pp_objects ); + p_this->p_libvlc->pp_objects = NULL; + + vlc_mutex_destroy( &structure_lock ); + } + else { int i_index; - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); + /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's + * useless to try and recover anything if pp_objects gets smashed. */ i_index = FindIndex( p_this, p_this->p_libvlc->pp_objects, p_this->p_libvlc->i_objects ); memmove( p_this->p_libvlc->pp_objects + i_index, @@ -259,13 +277,7 @@ void __vlc_object_destroy( vlc_object_t *p_this ) realloc( p_this->p_libvlc->pp_objects, (p_this->p_libvlc->i_objects - 1) * sizeof(vlc_object_t *) ); - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); - } - else - { - /* We are the root object ... no need to lock. */ - free( p_this->p_libvlc->pp_objects ); - p_this->p_libvlc->pp_objects = NULL; + vlc_mutex_unlock( &structure_lock ); } p_this->p_libvlc->i_objects--; @@ -286,13 +298,13 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode ) { vlc_object_t *p_found; - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); /* If we are of the requested type ourselves, don't look further */ if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type ) { p_this->i_refcount++; - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); return p_this; } @@ -307,7 +319,7 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode ) p_found = FindObject( p_this, i_type, i_mode ); } - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); return p_found; } @@ -317,9 +329,9 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode ) *****************************************************************************/ void __vlc_object_yield( vlc_object_t *p_this ) { - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); p_this->i_refcount++; - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -327,9 +339,9 @@ void __vlc_object_yield( vlc_object_t *p_this ) *****************************************************************************/ void __vlc_object_release( vlc_object_t *p_this ) { - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); p_this->i_refcount--; - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -340,7 +352,7 @@ void __vlc_object_release( vlc_object_t *p_this ) *****************************************************************************/ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) { - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); /* Attach the parent to its child */ p_this->p_parent = p_parent; @@ -357,7 +369,7 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) SetAttachment( p_this, VLC_TRUE ); } - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -367,11 +379,11 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) *****************************************************************************/ void __vlc_object_detach( vlc_object_t *p_this ) { - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); if( !p_this->p_parent ) { msg_Err( p_this, "object is not attached" ); - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); return; } @@ -382,7 +394,7 @@ void __vlc_object_detach( vlc_object_t *p_this ) } DetachObject( p_this ); - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -395,7 +407,7 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode ) { vlc_list_t *p_list = NewList(); - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); /* Look for the objects */ if( (i_mode & 0x000f) == FIND_ANYWHERE ) @@ -419,7 +431,7 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode ) msg_Err( p_this, "unimplemented!" ); } - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); return p_list; } @@ -434,7 +446,7 @@ void __vlc_liststructure( vlc_object_t *p_this ) { vlc_object_t **pp_current, **pp_end; - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); pp_current = p_this->p_libvlc->pp_objects; pp_end = pp_current + p_this->p_libvlc->i_objects; @@ -453,7 +465,7 @@ void __vlc_liststructure( vlc_object_t *p_this ) } } - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -466,10 +478,10 @@ void __vlc_dumpstructure( vlc_object_t *p_this ) { char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1]; - vlc_mutex_lock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); psz_foo[0] = '|'; DumpStructure( p_this, 0, psz_foo ); - vlc_mutex_unlock( &p_this->p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } /***************************************************************************** @@ -482,10 +494,9 @@ void vlc_list_release( vlc_list_t *p_list ) { if( p_list->i_count ) { - libvlc_t * p_libvlc = p_list->pp_objects[0]->p_libvlc; vlc_object_t ** pp_current = p_list->pp_objects; - vlc_mutex_lock( &p_libvlc->structure_lock ); + vlc_mutex_lock( &structure_lock ); while( pp_current[0] ) { @@ -493,7 +504,7 @@ void vlc_list_release( vlc_list_t *p_list ) pp_current++; } - vlc_mutex_unlock( &p_libvlc->structure_lock ); + vlc_mutex_unlock( &structure_lock ); } free( p_list ); diff --git a/src/misc/threads.c b/src/misc/threads.c index 019d5c2112..8ce3bd10c7 100644 --- a/src/misc/threads.c +++ b/src/misc/threads.c @@ -2,7 +2,7 @@ * threads.c : threads implementation for the VideoLAN client ***************************************************************************** * Copyright (C) 1999, 2000, 2001, 2002 VideoLAN - * $Id: threads.c,v 1.20 2002/10/04 12:01:40 gbazin Exp $ + * $Id: threads.c,v 1.21 2002/10/04 18:07:22 sam Exp $ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -25,6 +25,8 @@ #include +#include + #define VLC_THREADS_UNINITIALIZED 0 #define VLC_THREADS_PENDING 1 #define VLC_THREADS_ERROR 2 @@ -44,6 +46,22 @@ static volatile int i_initializations = 0; #elif defined( HAVE_KERNEL_SCHEDULER_H ) #endif +/***************************************************************************** + * Global variable for named mutexes + *****************************************************************************/ +typedef struct vlc_namedmutex_t vlc_namedmutex_t; +struct vlc_namedmutex_t +{ + vlc_mutex_t lock; + + char *psz_name; + int i_usage; + vlc_namedmutex_t *p_next; +}; + +static vlc_namedmutex_t *p_named_list = NULL; +static vlc_mutex_t named_lock; + /***************************************************************************** * vlc_threads_init: initialize threads system ***************************************************************************** @@ -110,7 +128,7 @@ int __vlc_threads_init( vlc_object_t *p_this ) #elif defined( HAVE_KERNEL_SCHEDULER_H ) #endif - vlc_mutex_init( p_libvlc, &p_libvlc->global_lock ); + vlc_mutex_init( p_libvlc, &named_lock ); if( i_ret ) { @@ -303,6 +321,99 @@ int __vlc_mutex_init( vlc_object_t *p_this, vlc_mutex_t *p_mutex ) #endif } +/***************************************************************************** + * vlc_mutex_need: create a global mutex from its name + *****************************************************************************/ +vlc_mutex_t * __vlc_mutex_need( vlc_object_t *p_this, char *psz_name ) +{ + vlc_namedmutex_t *p_named; + + vlc_mutex_lock( &named_lock ); + + p_named = p_named_list; + while( p_named ) + { + if( !strcmp( psz_name, p_named->psz_name ) ) + { + break; + } + p_named = p_named->p_next; + } + + if( p_named ) + { + p_named->i_usage++; + } + else + { + p_named = malloc( sizeof( vlc_namedmutex_t ) ); + vlc_mutex_init( p_this, &p_named->lock ); + p_named->psz_name = strdup( psz_name ); + p_named->i_usage = 1; + p_named->p_next = p_named_list; + p_named_list = p_named; + } + + vlc_mutex_unlock( &named_lock ); + + return &p_named->lock; +} + +/***************************************************************************** + * vlc_mutex_unneed: destroy a global mutex from its name + *****************************************************************************/ +void __vlc_mutex_unneed( vlc_object_t *p_this, char *psz_name ) +{ + vlc_namedmutex_t *p_named, *p_prev; + + vlc_mutex_lock( &named_lock ); + + p_named = p_named_list; + p_prev = NULL; + while( p_named ) + { + if( !strcmp( psz_name, p_named->psz_name ) ) + { + break; + } + p_prev = p_named; + p_named = p_named->p_next; + } + + if( p_named ) + { + p_named->i_usage--; + + if( p_named->i_usage <= 0 ) + { + /* Unlink named mutex */ + if( p_prev ) + { + p_prev->p_next = p_named->p_next; + } + else + { + p_named_list = p_named->p_next; + } + + /* Release this lock as soon as possible */ + vlc_mutex_unlock( &named_lock ); + + vlc_mutex_destroy( &p_named->lock ); + free( p_named->psz_name ); + free( p_named ); + + return; + } + } + else + { + msg_Err( p_this, "no named mutex called %s", psz_name ); + } + + vlc_mutex_unlock( &named_lock ); +} + /***************************************************************************** * vlc_mutex_destroy: destroy a mutex, inner version *****************************************************************************/ -- GitLab