Fixes some concurrency safetiness problems.
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
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;
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 );
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
if ( name[ 0 ] == list->name[ i ][ 0 ] && !strcmp( list->name[ i ], name ) )
value = list->value[ i ];
}
+ mlt_properties_unlock( self );
return value;
}
{
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 )
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.
int i = 0;
// Locate the item
+ mlt_properties_lock( self );
for ( i = 0; i < list->count; i ++ )
{
if ( !strcmp( list->name[ i ], source ) )
break;
}
}
+ mlt_properties_unlock( self );
}
return value != NULL;
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 );
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 );
+}
* \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>
*
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
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 )
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( ) );
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 );