From 5e12f8d2792991db7e4e7a86c1e3585a56b16e4e Mon Sep 17 00:00:00 2001 From: ddennedy Date: Mon, 30 Jun 2008 01:53:07 +0000 Subject: [PATCH] mlt_properties.c, mlt_service.c: bugfix to make reference counting and service closure truly thread-safe. As it was, reference count increment and decrement operations were not atomic and not protected comprehensively. git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@1154 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/mlt_properties.c | 19 ++++++++++++++----- src/framework/mlt_service.c | 6 ------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index 4e3f22b..7e55da9 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include #include @@ -46,6 +46,7 @@ typedef struct int size; mlt_properties mirror; int ref_count; + pthread_mutex_t mutex; } property_list; @@ -82,6 +83,7 @@ int mlt_properties_init( mlt_properties this, void *child ) // Increment the ref count ( ( property_list * )this->local )->ref_count = 1; + pthread_mutex_init( &( ( property_list * )this->local )->mutex, NULL );; } // Check that initialisation was successful @@ -186,12 +188,15 @@ static inline void mlt_properties_do_mirror( mlt_properties this, const char *na int mlt_properties_inc_ref( mlt_properties this ) { + int result = 0; if ( this != NULL ) { property_list *list = this->local; - return ++ list->ref_count; + pthread_mutex_lock( &list->mutex ); + result = ++ list->ref_count; + pthread_mutex_unlock( &list->mutex ); } - return 0; + return result; } /** Maintain ref count to allow multiple uses of an mlt object. @@ -199,12 +204,15 @@ int mlt_properties_inc_ref( mlt_properties this ) int mlt_properties_dec_ref( mlt_properties this ) { + int result = 0; if ( this != NULL ) { property_list *list = this->local; - return -- list->ref_count; + pthread_mutex_lock( &list->mutex ); + result = -- list->ref_count; + pthread_mutex_unlock( &list->mutex ); } - return 0; + return result; } /** Return the ref count of this object. @@ -903,6 +911,7 @@ void mlt_properties_close( mlt_properties this ) } // Clear up the list + pthread_mutex_destroy( &list->mutex ); free( list->name ); free( list->value ); free( list ); diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 9201865..04d929a 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -188,11 +188,7 @@ int mlt_service_connect_producer( mlt_service this, mlt_service producer, int in // Increment the reference count on this producer if ( producer != NULL ) - { - mlt_service_lock( producer ); mlt_properties_inc_ref( MLT_SERVICE_PROPERTIES( producer ) ); - mlt_service_unlock( producer ); - } // Now we disconnect the producer service from its consumer mlt_service_disconnect( producer ); @@ -499,10 +495,8 @@ mlt_profile mlt_service_profile( mlt_service this ) void mlt_service_close( mlt_service this ) { - mlt_service_lock( this ); if ( this != NULL && mlt_properties_dec_ref( MLT_SERVICE_PROPERTIES( this ) ) <= 0 ) { - mlt_service_unlock( this ); if ( this->close != NULL ) { this->close( this->close_object ); -- 1.7.4.4