]> git.sesse.net Git - mlt/commitdiff
Add mlt_properties_lock and _unlock.
authorDan Dennedy <dan@dennedy.org>
Sun, 27 Mar 2011 16:49:40 +0000 (09:49 -0700)
committerDan Dennedy <dan@dennedy.org>
Sun, 27 Mar 2011 16:49:40 +0000 (09:49 -0700)
Fixes some concurrency safetiness problems.

src/framework/mlt_playlist.c
src/framework/mlt_producer.c
src/framework/mlt_properties.c
src/framework/mlt_properties.h
src/framework/mlt_tractor.c
src/mlt++/MltProperties.cpp
src/mlt++/MltProperties.h

index 10975bfb14f91fed93b3a0075c6b9d07f463e8cd..3f8f36895d1129d1d02437046e5b2e5e90edb839 100644 (file)
@@ -979,12 +979,14 @@ int mlt_playlist_split( mlt_playlist self, int clip, mlt_position position )
                                mlt_producer split = mlt_producer_cut( entry->producer, in + position + 1, out );
                                mlt_properties split_properties = MLT_PRODUCER_PROPERTIES( split );
                                mlt_playlist_insert( self, split, clip + 1, 0, -1 );
+                               mlt_properties_lock( entry_properties );
                                for ( i = 0; i < mlt_properties_count( entry_properties ); i ++ )
                                {
                                        char *name = mlt_properties_get_name( entry_properties, i );
                                        if ( name != NULL && !strncmp( name, "meta.", 5 ) )
                                                mlt_properties_set( split_properties, name, mlt_properties_get_value( entry_properties, i ) );
                                }
+                               mlt_properties_unlock( entry_properties );
                                mlt_producer_close( split );
                        }
                        else
index e49f1395e54fecc3c572e0ef69a3d78c80920617..72e291a2332857a3e7c9908da51e9360e111201a 100644 (file)
@@ -656,15 +656,17 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind
                int i = 0;
                mlt_properties p_props = MLT_PRODUCER_PROPERTIES( self );
                mlt_properties f_props = MLT_FRAME_PROPERTIES( *frame );
+               mlt_properties_lock( p_props );
                int count = mlt_properties_count( p_props );
                for ( i = 0; i < count; i ++ )
                {
                        char *name = mlt_properties_get_name( p_props, i );
                        if ( !strncmp( name, "meta.", 5 ) )
-                               mlt_properties_set( f_props, name, mlt_properties_get( p_props, name ) );
+                               mlt_properties_set( f_props, name, mlt_properties_get_value( p_props, i ) );
                        else if ( !strncmp( name, "set.", 4 ) )
-                               mlt_properties_set( f_props, name + 4, mlt_properties_get( p_props, name ) );
+                               mlt_properties_set( f_props, name + 4, mlt_properties_get_value( p_props, i ) );
                }
+               mlt_properties_unlock( p_props );
        }
 
        return result;
@@ -948,7 +950,7 @@ int mlt_producer_optimise( mlt_producer self )
                        int count = 0;
                        int clones = 0;
                        int max_clones = 0;
-                       mlt_producer producer = mlt_properties_get_data( producers, name, &count );
+                       mlt_producer producer = mlt_properties_get_data_at( producers, k, &count );
                        if ( producer != NULL && count > 1 )
                        {
                                clip_references *refs = mlt_properties_get_data( properties, name, &count );
index 95a560374dcffcfb12b5410980745610d0c35587..a8c2d865d7217cee5dc4447021655c856bdbd2e1 100644 (file)
@@ -348,8 +348,10 @@ static inline mlt_property mlt_properties_find( mlt_properties self, const char
        property_list *list = self->local;
        mlt_property value = NULL;
        int key = generate_hash( name );
-       int i = list->hash[ key ] - 1;
 
+       mlt_properties_lock( self );
+
+       int i = list->hash[ key ] - 1;
        if ( i >= 0 )
        {
                // Check if we're hashed
@@ -363,6 +365,7 @@ static inline mlt_property mlt_properties_find( mlt_properties self, const char
                        if ( name[ 0 ] == list->name[ i ][ 0 ] && !strcmp( list->name[ i ], name ) )
                                value = list->value[ i ];
        }
+       mlt_properties_unlock( self );
 
        return value;
 }
@@ -379,6 +382,9 @@ static mlt_property mlt_properties_add( mlt_properties self, const char *name )
 {
        property_list *list = self->local;
        int key = generate_hash( name );
+       mlt_property result;
+
+       mlt_properties_lock( self );
 
        // Check that we have space and resize if necessary
        if ( list->count == list->size )
@@ -397,7 +403,11 @@ static mlt_property mlt_properties_add( mlt_properties self, const char *name )
                list->hash[ key ] = list->count + 1;
 
        // Return and increment count accordingly
-       return list->value[ list->count ++ ];
+       result = list->value[ list->count ++ ];
+
+       mlt_properties_unlock( self );
+
+       return result;
 }
 
 /** Fetch a property by name and add one if not found.
@@ -938,6 +948,7 @@ int mlt_properties_rename( mlt_properties self, const char *source, const char *
                int i = 0;
 
                // Locate the item
+               mlt_properties_lock( self );
                for ( i = 0; i < list->count; i ++ )
                {
                        if ( !strcmp( list->name[ i ], source ) )
@@ -948,6 +959,7 @@ int mlt_properties_rename( mlt_properties self, const char *source, const char *
                                break;
                        }
                }
+               mlt_properties_unlock( self );
        }
 
        return value != NULL;
@@ -1115,7 +1127,9 @@ int mlt_properties_dir_list( mlt_properties self, const char *dirname, const cha
        if ( sort && mlt_properties_count( self ) )
        {
                property_list *list = self->local;
+               mlt_properties_lock( self );
                qsort( list->value, mlt_properties_count( self ), sizeof( mlt_property ), mlt_compare );
+               mlt_properties_unlock( self );
        }
 
        return mlt_properties_count( self );
@@ -1752,3 +1766,27 @@ char *mlt_properties_serialise_yaml( mlt_properties self )
        strbuf_close( b );
        return ret;
 }
+
+/** Protect a properties list against concurrent access.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ */
+
+void mlt_properties_lock( mlt_properties self )
+{
+       if ( self )
+               pthread_mutex_lock( &( ( property_list* )( self->local ) )->mutex );
+}
+
+/** End protecting a properties list against concurrent access.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ */
+
+void mlt_properties_unlock( mlt_properties self )
+{
+       if ( self )
+               pthread_mutex_unlock( &( ( property_list* )( self->local ) )->mutex );
+}
index c5e15cc153707ee832dff2099bdbf9ee10cb7086..55f9b0d6b49da0483a51dbe82ea5c493d130a0e6 100644 (file)
@@ -3,7 +3,7 @@
  * \brief Properties class declaration
  * \see mlt_properties_s
  *
- * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2011 Ushodaya Enterprises Limited
  * \author Charles Yates <charles.yates@pandora.be>
  * \author Dan Dennedy <dan@dennedy.org>
  *
@@ -83,5 +83,7 @@ extern void mlt_properties_close( mlt_properties self );
 extern int mlt_properties_is_sequence( mlt_properties self );
 extern mlt_properties mlt_properties_parse_yaml( const char *file );
 extern char *mlt_properties_serialise_yaml( mlt_properties self );
+extern void mlt_properties_lock( mlt_properties self );
+extern void mlt_properties_unlock( mlt_properties self );
 
 #endif
index e509fe2795cdda99c918a03180b75810414c91f9..e8d0352a4872b07ee0c3802d4a2feb9493de57dd 100644 (file)
@@ -395,14 +395,16 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra
                                temp_properties = MLT_FRAME_PROPERTIES( temp );
 
                                // Pass all unique meta properties from the producer's frame to the new frame
+                               mlt_properties_lock( temp_properties );
                                int props_count = mlt_properties_count( temp_properties );
                                int j;
                                for ( j = 0; j < props_count; j ++ )
                                {
                                        char *name = mlt_properties_get_name( temp_properties, j );
                                        if ( !strncmp( name, "meta.", 5 ) && !mlt_properties_get( frame_properties, name ) )
-                                               mlt_properties_set( frame_properties, name, mlt_properties_get( temp_properties, name ) );
+                                               mlt_properties_set( frame_properties, name, mlt_properties_get_value( temp_properties, j ) );
                                }
+                               mlt_properties_unlock( temp_properties );
 
                                // Copy the format conversion virtual functions
                                if ( ! (*frame)->convert_image && temp->convert_image )
index 9280dddecb3c4a096ea2329410cabadeafb0b52c..8317294c285f3850e795c80b9d3f5bcc271dbd82 100644 (file)
@@ -82,6 +82,16 @@ int Properties::ref_count( )
        return mlt_properties_ref_count( get_properties( ) );
 }
 
+void Properties::lock( )
+{
+       mlt_properties_lock( get_properties( ) );
+}
+
+void Properties::unlock( )
+{
+       mlt_properties_unlock( get_properties( ) );
+}
+
 void Properties::block( void *object )
 {
        mlt_events_block( get_properties( ), object != NULL ? object : get_properties( ) );
index 07d840ef9f13454f6cfe0605f8a943934ad715e3..fce173ff0adf3d6a55aff030b6f83ba4a96a664f 100644 (file)
@@ -49,6 +49,8 @@ namespace Mlt
                        int inc_ref( );
                        int dec_ref( );
                        int ref_count( );
+                       void lock( );
+                       void unlock( );
                        void block( void *object = NULL );
                        void unblock( void *object = NULL );
                        void fire_event( const char *event );