From 56ec18e7f4dfd8c801ac2f6268856e3e9175e091 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 16 Sep 2007 12:27:40 +0000 Subject: [PATCH] block_FifoWake: force the block_FifoGet()'ing thread to wakeup without queuing any data - this is mostly useful when quitting --- include/vlc_block.h | 3 +++ src/misc/block.c | 30 ++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/vlc_block.h b/include/vlc_block.h index 8c09f9436e..00687afe40 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -262,6 +262,8 @@ static inline block_t *block_ChainGather( block_t *p_list ) * only one getting data from the fifo. * - block_FifoCount : how many packets are waiting in the fifo * - block_FifoSize : how many cumulated bytes are waiting in the fifo + * - block_FifoWake : wake ups a thread with block_FifoGet() = NULL + * (this is used to wakeup a thread when there is no data to queue) ****************************************************************************/ #define block_FifoNew( a ) __block_FifoNew( VLC_OBJECT(a) ) @@ -269,6 +271,7 @@ VLC_EXPORT( block_fifo_t *, __block_FifoNew, ( vlc_object_t * ) ); VLC_EXPORT( void, block_FifoRelease, ( block_fifo_t * ) ); VLC_EXPORT( void, block_FifoEmpty, ( block_fifo_t * ) ); VLC_EXPORT( int, block_FifoPut, ( block_fifo_t *, block_t * ) ); +VLC_EXPORT( void, block_FifoWake, ( block_fifo_t * ) ); VLC_EXPORT( block_t *, block_FifoGet, ( block_fifo_t * ) ); VLC_EXPORT( block_t *, block_FifoShow, ( block_fifo_t * ) ); VLC_EXPORT( size_t, block_FifoSize, ( const block_fifo_t *p_fifo ) ); diff --git a/src/misc/block.c b/src/misc/block.c index cbfd5e9cb7..12fa046505 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -160,10 +160,11 @@ struct block_fifo_t vlc_mutex_t lock; /* fifo data lock */ vlc_cond_t wait; /* fifo data conditional variable */ - size_t i_depth; block_t *p_first; block_t **pp_last; + size_t i_depth; size_t i_size; + vlc_bool_t b_force_wake; }; block_fifo_t *__block_FifoNew( vlc_object_t *p_obj ) @@ -173,9 +174,10 @@ block_fifo_t *__block_FifoNew( vlc_object_t *p_obj ) p_fifo = malloc( sizeof( block_fifo_t ) ); vlc_mutex_init( p_obj, &p_fifo->lock ); vlc_cond_init( p_obj, &p_fifo->wait ); - p_fifo->i_depth = p_fifo->i_size = 0; p_fifo->p_first = NULL; p_fifo->pp_last = &p_fifo->p_first; + p_fifo->i_depth = p_fifo->i_size = 0; + p_fifo->b_force_wake = VLC_FALSE; return p_fifo; } @@ -233,22 +235,38 @@ int block_FifoPut( block_fifo_t *p_fifo, block_t *p_block ) return i_size; } +void block_FifoWake( block_fifo_t *p_fifo ) +{ + vlc_mutex_lock( &p_fifo->lock ); + if( p_fifo->p_first == NULL ) + p_fifo->b_force_wake = VLC_TRUE; + vlc_cond_signal( &p_fifo->wait ); + vlc_mutex_unlock( &p_fifo->lock ); +} + block_t *block_FifoGet( block_fifo_t *p_fifo ) { block_t *b; vlc_mutex_lock( &p_fifo->lock ); - /* We do a while here because there is a race condition in the - * win32 implementation of vlc_cond_wait() (We can't be sure the fifo - * hasn't been emptied again since we were signaled). */ - while( p_fifo->p_first == NULL ) + /* Remember vlc_cond_wait() may cause spurious wakeups + * (on both Win32 and POSIX) */ + while( ( p_fifo->p_first == NULL ) && !p_fifo->b_force_wake ) { vlc_cond_wait( &p_fifo->wait, &p_fifo->lock ); } b = p_fifo->p_first; + p_fifo->b_force_wake = VLC_FALSE; + if( b == NULL ) + { + /* Forced wakeup */ + vlc_mutex_unlock( &p_fifo->lock ); + return NULL; + } + p_fifo->p_first = b->p_next; p_fifo->i_depth--; p_fifo->i_size -= b->i_buffer; -- 2.39.2