Changeset d9b511137a52356cbf7941abd1e6a46ea078f9bc

Show
Ignore:
Timestamp:
01/21/08 21:22:46 (8 months ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1200946966 +0000
git-parent:

[8f92249ae4cc44e2eceecfba0610e43174813156]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1200946966 +0000
Message:

Remove the requirement for vlc object to be locked when invoking waitpipe.
This is so that the net_* functions can use it without making pushing locking assumption on their caller.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/libvlc.h

    r2ef3494 rd9b5111  
    110110 
    111111    /* Objects thread synchronization */ 
     112    vlc_bool_t      b_signaled; 
    112113    int             pipes[2]; 
     114    vlc_spinlock_t  spin; 
    113115 
    114116    /* Objects management */ 
  • src/misc/objects.c

    r6cf8fa7 rd9b5111  
    196196    vlc_cond_init( p_new, &p_new->object_wait ); 
    197197    vlc_mutex_init( p_new, &p_priv->var_lock ); 
     198    vlc_spin_init( &p_priv->spin ); 
    198199    p_priv->pipes[0] = p_priv->pipes[1] = -1; 
    199200 
     
    444445    vlc_mutex_destroy( &p_this->object_lock ); 
    445446    vlc_cond_destroy( &p_this->object_wait ); 
     447    vlc_spin_destroy( &p_priv->spin ); 
    446448    if( p_priv->pipes[0] != -1 ) 
    447449        close( p_priv->pipes[0] ); 
     
    533535 * Also note that, as with vlc_object_wait(), there may be spurious wakeups. 
    534536 * 
    535  * @param obj object that would be signaled (object lock MUST hold) 
     537 * @param obj object that would be signaled 
    536538 * @return a readable pipe descriptor, or -1 on error. 
    537539 */ 
    538540int __vlc_object_waitpipe( vlc_object_t *obj ) 
    539541{ 
    540     int *pipes = obj->p_internals->pipes; 
    541     vlc_assert_locked( &obj->object_lock ); 
    542  
    543     if( pipes[1] == -1 ) 
    544     { 
    545         /* This can only ever happen if someone killed us without locking */ 
    546         assert( pipes[0] == -1 ); 
    547  
    548         if( pipe( pipes ) ) 
     542    int pfd[2] = { -1, -1 }; 
     543    struct vlc_object_internals_t *internals = obj->p_internals; 
     544    vlc_bool_t race = VLC_FALSE, signaled = VLC_FALSE; 
     545 
     546    vlc_spin_lock (&internals->spin); 
     547    if (internals->pipes[0] == -1) 
     548    { 
     549        /* This can only ever happen if someone killed us without locking: */ 
     550        assert (internals->pipes[1] == -1); 
     551        vlc_spin_unlock (&internals->spin); 
     552 
     553        if (pipe (pfd)) 
    549554            return -1; 
    550     } 
    551  
    552     return pipes[0]; 
     555 
     556        vlc_spin_lock (&internals->spin); 
     557        signaled = internals->b_signaled; 
     558        if ((!signaled) && (internals->pipes[0] == -1)) 
     559        { 
     560            internals->pipes[0] = pfd[0]; 
     561            internals->pipes[1] = pfd[1]; 
     562        } 
     563    } 
     564    vlc_spin_unlock (&internals->spin); 
     565 
     566    if (race || signaled) 
     567    { 
     568        close (pfd[0]); 
     569        close (pfd[1]); 
     570 
     571        if (signaled) 
     572        {   /* vlc_object_signal() was already invoked! */ 
     573            errno = EINTR; 
     574            return -1; 
     575        } 
     576    } 
     577 
     578    return internals->pipes[0]; 
    553579} 
    554580 
     
    563589vlc_bool_t __vlc_object_wait( vlc_object_t *obj ) 
    564590{ 
     591    int fd; 
     592 
    565593    vlc_assert_locked( &obj->object_lock ); 
    566594 
    567     int fd = obj->p_internals->pipes[0]; 
    568     if( fd != -1
    569     { 
    570         while (read (fd, &(char){ 0 }, 1  < 0)); 
     595    fd = obj->p_internals->pipes[0]; 
     596    if (fd != -1
     597    { 
     598        while (read (fd, &(char){ 0 }, 1)  < 0); 
    571599        return obj->b_die; 
    572600    } 
    573601 
    574602    vlc_cond_wait( &obj->object_wait, &obj->object_lock ); 
     603    obj->p_internals->b_signaled = VLC_FALSE; 
    575604    return obj->b_die; 
    576605} 
     
    634663void __vlc_object_signal_unlocked( vlc_object_t *obj ) 
    635664{ 
    636     vlc_assert_locked( &obj->object_lock ); 
    637  
    638     int fd = obj->p_internals->pipes[1]; 
     665    struct vlc_object_internals_t *internals = obj->p_internals; 
     666    int fd; 
     667 
     668    vlc_assert_locked (&obj->object_lock); 
     669 
     670    vlc_spin_lock (&internals->spin); 
     671    fd = internals->pipes[1]; 
     672    internals->b_signaled = VLC_TRUE; 
     673    vlc_spin_unlock (&internals->spin); 
     674 
    639675    if( fd != -1 ) 
    640676        while( write( fd, &(char){ 0 }, 1 ) < 0 );