]> git.sesse.net Git - mlt/commitdiff
Fix some race conditions in mlt_consumer.
authorDan Dennedy <dan@dennedy.org>
Sun, 22 Sep 2013 01:34:01 +0000 (18:34 -0700)
committerDan Dennedy <dan@dennedy.org>
Sun, 22 Sep 2013 01:34:01 +0000 (18:34 -0700)
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

index 0a47eaa67486ef4fbc1f139967d1fefe3feef181..87ba312099b093d45230c0eb1ff338dc80104fc3 100644 (file)
@@ -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 )