From f26c43f62082424eeb9dc5a1ebed0686ce28d40d Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Sat, 21 Sep 2013 18:34:01 -0700 Subject: [PATCH] Fix some race conditions in mlt_consumer. OpenGL apps need to receive consumer-thread-stopped *after* all of the frames are closed. Otherwise, it may cleanup the GL context before frames holding context resources are closed. Some consumer threads call mlt_consumer_purge(). --- src/framework/mlt_consumer.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index 0a47eaa6..87ba3120 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -909,7 +909,6 @@ static void *consumer_read_ahead_thread( void *arg ) // Remove the last frame mlt_frame_close( frame ); - mlt_events_fire( properties, "consumer-thread-stopped", NULL ); return NULL; } @@ -1025,7 +1024,6 @@ static void *consumer_worker_thread( void *arg ) pthread_cond_broadcast( &priv->done_cond ); pthread_mutex_unlock( &priv->done_mutex ); } - mlt_events_fire( properties, "consumer-thread-stopped", NULL ); return NULL; } @@ -1196,6 +1194,8 @@ static void consumer_read_ahead_stop( mlt_consumer self ) // Close the queue mlt_deque_close( priv->queue ); + + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", NULL ); } } @@ -1261,6 +1261,8 @@ static void consumer_work_stop( mlt_consumer self ) // Close the queues mlt_deque_close( priv->queue ); mlt_deque_close( priv->worker_threads ); + + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", NULL ); } } @@ -1284,17 +1286,18 @@ void mlt_consumer_purge( mlt_consumer self ) pthread_cond_broadcast( &priv->put_cond ); pthread_mutex_unlock( &priv->put_mutex ); - if ( priv->started && priv->real_time ) - pthread_mutex_lock( &priv->queue_mutex ); - if ( self->purge ) self->purge( self ); + pthread_mutex_lock( &priv->queue_mutex ); while ( priv->started && mlt_deque_count( priv->queue ) ) mlt_frame_close( mlt_deque_pop_back( priv->queue ) ); + pthread_mutex_unlock( &priv->queue_mutex ); + if ( priv->started && priv->real_time ) { priv->is_purge = 1; + pthread_mutex_lock( &priv->queue_mutex ); pthread_cond_broadcast( &priv->queue_cond ); pthread_mutex_unlock( &priv->queue_mutex ); if ( abs( priv->real_time ) > 1 ) -- 2.39.2