[vlc-devel] commit: Added lock around es_out for multiple thread access. ( Laurent Aimar )
git version control
git at videolan.org
Sat Nov 1 16:47:23 CET 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Sat Nov 1 16:19:52 2008 +0100| [007185b1ab1125ec04c9aa5bea1446f802dd5d5f] | committer: Laurent Aimar
Added lock around es_out for multiple thread access.
It should fix race conditions when using stream demuxer.
It is a temporary way until I finish a few es_out modification.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=007185b1ab1125ec04c9aa5bea1446f802dd5d5f
---
src/input/es_out.c | 66 ++++++++++++++++++++++++++++++++++++++++++---------
src/input/es_out.h | 3 ++
src/input/input.c | 21 +++++++++++++++-
3 files changed, 77 insertions(+), 13 deletions(-)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 986ada5..c4e46e3 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -99,6 +99,9 @@ struct es_out_sys_t
{
input_thread_t *p_input;
+ /* */
+ vlc_mutex_t lock;
+
/* all programs */
int i_pgrm;
es_out_pgrm_t **pgrm;
@@ -203,10 +206,11 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
vlc_value_t val;
int i;
- es_out_t *out = malloc( sizeof( es_out_t ) );
- if( !out ) return NULL;
+ es_out_t *out = malloc( sizeof( *out ) );
+ if( !out )
+ return NULL;
- es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) );
+ es_out_sys_t *p_sys = malloc( sizeof( *p_sys ) );
if( !p_sys )
{
free( out );
@@ -220,6 +224,8 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
out->p_sys = p_sys;
out->b_sout = p_input->p->p_sout != NULL;
+
+ vlc_mutex_init_recursive( &p_sys->lock );
p_sys->p_input = p_input;
p_sys->b_active = false;
@@ -352,6 +358,7 @@ void input_EsOutDelete( es_out_t *out )
free( p_pgrm );
}
TAB_CLEAN( p_sys->i_pgrm, p_sys->pgrm );
+ vlc_mutex_destroy( &p_sys->lock );
free( p_sys );
free( out );
@@ -362,7 +369,7 @@ es_out_id_t *input_EsOutGetFromID( es_out_t *out, int i_id )
int i;
if( i_id < 0 )
{
- /* Special HACK, -i_id is tha cat of the stream */
+ /* Special HACK, -i_id is the cat of the stream */
return (es_out_id_t*)((uint8_t*)NULL-i_id);
}
@@ -652,6 +659,15 @@ void input_EsOutFrameNext( es_out_t *out )
p_sys->i_preroll_end = -1;
}
+void input_EsOutLock( es_out_t *out )
+{
+ vlc_mutex_lock( &out->p_sys->lock );
+}
+void input_EsOutUnlock( es_out_t *out )
+{
+ vlc_mutex_unlock( &out->p_sys->lock );
+}
+
/*****************************************************************************
*
*****************************************************************************/
@@ -1275,19 +1291,21 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
- es_out_id_t *es = malloc( sizeof( es_out_id_t ) );
- es_out_pgrm_t *p_pgrm = NULL;
- int i;
-
- if( !es ) return NULL;
-
if( fmt->i_group < 0 )
{
msg_Err( p_input, "invalid group number" );
- free( es );
return NULL;
}
+ es_out_id_t *es = malloc( sizeof( *es ) );
+ es_out_pgrm_t *p_pgrm = NULL;
+ int i;
+
+ if( !es )
+ return NULL;
+
+ vlc_mutex_lock( &p_sys->lock );
+
/* Search the program */
for( i = 0; i < p_sys->i_pgrm; i++ )
{
@@ -1391,6 +1409,8 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
EsOutAddInfo( out, es );
+ vlc_mutex_unlock( &p_sys->lock );
+
return es;
}
@@ -1790,6 +1810,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
+ vlc_mutex_lock( &p_sys->lock );
+
/* Mark preroll blocks */
if( p_sys->i_preroll_end >= 0 )
{
@@ -1806,6 +1828,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
if( !es->p_dec )
{
block_Release( p_block );
+ vlc_mutex_unlock( &p_sys->lock );
return VLC_SUCCESS;
}
@@ -1853,6 +1876,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
if( b_cc_new )
var_SetBool( p_sys->p_input, "intf-change", true );
+ vlc_mutex_unlock( &p_sys->lock );
+
return VLC_SUCCESS;
}
@@ -1865,6 +1890,8 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
bool b_reselect = false;
int i;
+ vlc_mutex_lock( &p_sys->lock );
+
/* We don't try to reselect */
if( es->p_dec )
{
@@ -1911,17 +1938,21 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
/* Re-select another track when needed */
if( b_reselect )
+ {
for( i = 0; i < p_sys->i_es; i++ )
{
if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat )
EsOutSelect( out, p_sys->es[i], false );
}
+ }
free( es->psz_language );
free( es->psz_language_code );
es_format_Clean( &es->fmt );
+ vlc_mutex_unlock( &p_sys->lock );
+
free( es );
}
@@ -1933,7 +1964,7 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
* \param args a variable list of arguments for the query
* \return VLC_SUCCESS or an error code
*/
-static int EsOutControl( es_out_t *out, int i_query, va_list args )
+static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
{
es_out_sys_t *p_sys = out->p_sys;
bool b, *pb;
@@ -2257,6 +2288,17 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
return VLC_EGENERIC;
}
}
+static int EsOutControl( es_out_t *out, int i_query, va_list args )
+{
+ es_out_sys_t *p_sys = out->p_sys;
+ int i_ret;
+
+ vlc_mutex_lock( &p_sys->lock );
+ i_ret = EsOutControlLocked( out, i_query, args );
+ vlc_mutex_unlock( &p_sys->lock );
+
+ return i_ret;
+}
/****************************************************************************
* LanguageGetName: try to expend iso639 into plain name
diff --git a/src/input/es_out.h b/src/input/es_out.h
index dbf79df..2766371 100644
--- a/src/input/es_out.h
+++ b/src/input/es_out.h
@@ -44,4 +44,7 @@ bool input_EsOutDecodersIsEmpty( es_out_t * );
bool input_EsOutIsBuffering( es_out_t * );
void input_EsOutFrameNext( es_out_t * );
+void input_EsOutLock( es_out_t * );
+void input_EsOutUnlock( es_out_t * );
+
#endif
diff --git a/src/input/input.c b/src/input/input.c
index 1720a1c..7e4c8f9 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -743,13 +743,18 @@ static void MainLoop( input_thread_t *p_input )
/* FIXME if p_input->i_state == PAUSE_S the access/access_demux
* is paused -> this may cause problem with some of them
* The same problem can be seen when seeking while paused */
+ input_EsOutLock( p_input->p->p_es_out );
b_paused = p_input->i_state == PAUSE_S &&
!input_EsOutIsBuffering( p_input->p->p_es_out );
+ input_EsOutUnlock( p_input->p->p_es_out );
if( !b_paused )
{
MainLoopDemux( p_input, &b_force_update, &i_start_mdate );
+
+ input_EsOutLock( p_input->p->p_es_out );
i_wakeup = input_EsOutGetWakeup( p_input->p->p_es_out );
+ input_EsOutUnlock( p_input->p->p_es_out );
}
/* */
@@ -764,6 +769,7 @@ static void MainLoop( input_thread_t *p_input )
while( !ControlPopNoLock( p_input, &i_type, &val, i_deadline ) )
{
msg_Dbg( p_input, "control type=%d", i_type );
+
if( Control( p_input, i_type, val ) )
b_force_update = true;
}
@@ -786,9 +792,11 @@ static void MainLoop( input_thread_t *p_input )
/* Check if i_wakeup is still valid */
if( i_wakeup != 0 )
{
+ input_EsOutLock( p_input->p->p_es_out );
mtime_t i_new_wakeup = input_EsOutGetWakeup( p_input->p->p_es_out );
if( !i_new_wakeup )
i_wakeup = 0;
+ input_EsOutUnlock( p_input->p->p_es_out );
}
} while( i_current < i_wakeup );
}
@@ -798,7 +806,11 @@ static void MainLoop( input_thread_t *p_input )
/* We have finish to demux data but not to play them */
while( vlc_object_alive( p_input ) )
{
- if( input_EsOutDecodersIsEmpty( p_input->p->p_es_out ) )
+ input_EsOutLock( p_input->p->p_es_out );
+ bool b_empty = input_EsOutDecodersIsEmpty( p_input->p->p_es_out );
+ input_EsOutUnlock( p_input->p->p_es_out );
+
+ if( b_empty )
break;
msg_Dbg( p_input, "waiting decoder fifos to empty" );
@@ -1547,6 +1559,8 @@ static bool Control( input_thread_t *p_input, int i_type,
if( !p_input )
return b_force_update;
+ input_EsOutLock( p_input->p->p_es_out );
+
switch( i_type )
{
case INPUT_CONTROL_SET_DIE:
@@ -2063,6 +2077,8 @@ static bool Control( input_thread_t *p_input, int i_type,
break;
}
+ input_EsOutUnlock( p_input->p->p_es_out );
+
return b_force_update;
}
@@ -3094,10 +3110,13 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for
if( count.i_int < list.p_list->i_count )
{
int i_id = list.p_list->p_values[count.i_int].i_int;
+
+ input_EsOutLock( p_input->p->p_es_out );
es_out_id_t *p_es = input_EsOutGetFromID( p_input->p->p_es_out, i_id );
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_DEFAULT, p_es );
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ES, p_es );
+ input_EsOutUnlock( p_input->p->p_es_out );
}
var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL );
}
More information about the vlc-devel
mailing list