Changeset a901e3b6074c1894f8e27039b5ad414df63bde75

Show
Ignore:
Timestamp:
08/07/07 17:22:53 (1 year ago)
Author:
Pierre d'Herbemont <pdherbemont@videolan.org>
git-committer:
Pierre d'Herbemont <pdherbemont@videolan.org> 1183908173 +0000
git-parent:

[2f6a9d1a2bad2eee1b8ea6330af1b7dc487008da]

git-author:
Pierre d'Herbemont <pdherbemont@videolan.org> 1183908173 +0000
Message:

Libvlc: Make medi_instance thread safe and implement the basics for refcounting.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/control/libvlc_internal.h

    r40fbcb7 ra901e3b  
    8787struct libvlc_media_instance_t 
    8888{ 
     89    int                i_refcount; 
     90    vlc_mutex_t        object_lock; 
    8991    int i_input_id;  /* Input object id. We don't use a pointer to 
    9092                        avoid any crash */ 
  • src/control/media_instance.c

    r23942f1 ra901e3b  
    3030/* 
    3131 * Release the associated input thread 
     32 * 
     33 * Object lock is NOT held. 
    3234 */ 
    3335static void release_input_thread( libvlc_media_instance_t *p_mi )  
     
    3739    libvlc_exception_t p_e; 
    3840 
    39     /* XXX: locking */ 
    4041    libvlc_exception_init( &p_e ); 
    4142 
     
    6364 * Retrieve the input thread. Be sure to release the object 
    6465 * once you are done with it. (libvlc Internal) 
     66 * 
     67 * Object lock is held. 
    6568 */ 
    6669input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi, 
     
    6972    input_thread_t *p_input_thread; 
    7073 
     74    vlc_mutex_lock( &p_mi->object_lock ); 
     75 
    7176    if( !p_mi || p_mi->i_input_id == -1 ) 
     77    { 
     78        vlc_mutex_unlock( &p_mi->object_lock ); 
    7279        RAISENULL( "Input is NULL" ); 
     80    } 
    7381 
    7482    p_input_thread = (input_thread_t*)vlc_object_get( 
     
    7684                                             p_mi->i_input_id ); 
    7785    if( !p_input_thread ) 
     86    { 
     87        vlc_mutex_unlock( &p_mi->object_lock ); 
    7888        RAISENULL( "Input does not exist" ); 
    79  
     89    } 
     90 
     91    vlc_mutex_unlock( &p_mi->object_lock ); 
    8092    return p_input_thread; 
    8193} 
     
    101113    p_mi->p_libvlc_instance = p_libvlc_instance; 
    102114    p_mi->i_input_id = -1; 
     115    /* refcount strategy: 
     116     * - All items created by _new start with a refcount set to 1 
     117     * - Accessor _release decrease the refcount by 1, if after that 
     118     *   operation the refcount is 0, the object is destroyed. 
     119     * - Accessor _retain increase the refcount by 1 (XXX: to implement) */ 
     120    p_mi->i_refcount = 1; 
     121    /* object_lock strategy: 
     122     * - No lock held in constructor 
     123     * - Lock when accessing all variable this lock is held 
     124     * - Lock when attempting to destroy the object the lock is also held */ 
     125    vlc_mutex_init( p_mi->p_libvlc_instance->p_libvlc_int, 
     126                    &p_mi->object_lock ); 
    103127 
    104128    return p_mi; 
     
    125149    p_mi->p_libvlc_instance = p_mi->p_md->p_libvlc_instance; 
    126150    p_mi->i_input_id = -1; 
     151    /* same strategy as before */ 
     152    p_mi->i_refcount = 1; 
     153    /* same strategy as before */ 
     154    vlc_mutex_init( p_mi->p_libvlc_instance->p_libvlc_int, 
     155                    &p_mi->object_lock ); 
    127156 
    128157    return p_mi; 
     
    167196/************************************************************************** 
    168197 * Destroy a Media Instance object (libvlc internal) 
     198 * 
     199 * Warning: No lock held here, but hey, this is internal. 
    169200 **************************************************************************/ 
    170201void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi ) 
     
    173204    libvlc_exception_t p_e; 
    174205 
    175     /* XXX: locking */ 
    176206    libvlc_exception_init( &p_e ); 
    177207 
     
    196226void libvlc_media_instance_release( libvlc_media_instance_t *p_mi ) 
    197227{ 
    198     /* XXX: locking */ 
    199  
    200228    if( !p_mi ) 
    201229        return; 
    202230 
     231    vlc_mutex_lock( &p_mi->object_lock ); 
     232     
     233    p_mi->i_refcount--; 
     234    if( p_mi->i_refcount > 0 ) 
     235    { 
     236        vlc_mutex_unlock( &p_mi->object_lock ); 
     237        return; 
     238    } 
     239 
    203240    release_input_thread( p_mi ); 
    204241 
    205242    libvlc_media_descriptor_destroy( p_mi->p_md ); 
    206243 
     244    vlc_mutex_unlock( &p_mi->object_lock ); 
    207245    free( p_mi ); 
    208246} 
     
    218256    (void)p_e; 
    219257 
    220     /* XXX : lock */ 
    221  
    222258    if( !p_mi ) 
    223259        return; 
    224260 
     261    vlc_mutex_lock( &p_mi->object_lock ); 
     262     
    225263    release_input_thread( p_mi ); 
    226264 
     
    230268    { 
    231269        p_mi->p_md = NULL; 
     270        vlc_mutex_unlock( &p_mi->object_lock ); 
    232271        return; /* It is ok to pass a NULL md */ 
    233272    } 
     
    239278    p_mi->p_libvlc_instance = p_md->p_libvlc_instance; 
    240279 
     280    vlc_mutex_unlock( &p_mi->object_lock ); 
    241281} 
    242282 
     
    265305    input_thread_t * p_input_thread; 
    266306 
    267     if( p_mi->i_input_id != -1)  
    268     { 
     307    vlc_mutex_lock( &p_mi->object_lock ); 
     308 
     309    if( p_input_thread = libvlc_get_input_thread( p_mi, p_e ) )  
     310    { 
     311        /* A thread alread exists, send it a play message */         
    269312        vlc_value_t val; 
    270313        val.i_int = PLAYING_S; 
    271314 
    272         /* A thread alread exists, send it a play message */ 
    273         p_input_thread = libvlc_get_input_thread( p_mi, p_e ); 
    274  
    275         if( !p_input_thread ) 
    276             return; 
    277  
    278315        input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, PLAYING_S ); 
    279316        vlc_object_release( p_input_thread ); 
     
    281318    } 
    282319 
     320    vlc_mutex_lock( &p_mi->object_lock ); 
     321     
    283322    if( !p_mi->p_md ) 
    284323    { 
    285324        libvlc_exception_raise( p_e, "no associated media descriptor" ); 
     325        vlc_mutex_unlock( &p_mi->object_lock ); 
    286326        return; 
    287327    } 
     
    293333    /* will be released in media_instance_release() */ 
    294334    vlc_object_yield( p_input_thread ); 
     335 
     336    vlc_mutex_unlock( &p_mi->object_lock ); 
    295337} 
    296338