Commit 46d6a5a4 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Simplify waitpipe.

The caller is going to call poll() or something, so locking a mutex is
surely not a performance issue.
parent 161532ab
...@@ -160,7 +160,6 @@ typedef struct vlc_object_internals_t ...@@ -160,7 +160,6 @@ typedef struct vlc_object_internals_t
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_cond_t wait; vlc_cond_t wait;
int pipes[2]; int pipes[2];
vlc_spinlock_t spin;
/* Objects management */ /* Objects management */
vlc_spinlock_t ref_spin; vlc_spinlock_t ref_spin;
......
...@@ -176,7 +176,6 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size, ...@@ -176,7 +176,6 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
vlc_cond_init( &p_priv->wait ); vlc_cond_init( &p_priv->wait );
vlc_mutex_init( &p_priv->var_lock ); vlc_mutex_init( &p_priv->var_lock );
vlc_cond_init( &p_priv->var_wait ); vlc_cond_init( &p_priv->var_wait );
vlc_spin_init( &p_priv->spin );
p_priv->pipes[0] = p_priv->pipes[1] = -1; p_priv->pipes[0] = p_priv->pipes[1] = -1;
p_priv->next = p_this; p_priv->next = p_this;
...@@ -309,7 +308,6 @@ static void vlc_object_destroy( vlc_object_t *p_this ) ...@@ -309,7 +308,6 @@ static void vlc_object_destroy( vlc_object_t *p_this )
vlc_spin_destroy( &p_priv->ref_spin ); vlc_spin_destroy( &p_priv->ref_spin );
vlc_mutex_destroy( &p_priv->lock ); vlc_mutex_destroy( &p_priv->lock );
vlc_cond_destroy( &p_priv->wait ); vlc_cond_destroy( &p_priv->wait );
vlc_spin_destroy( &p_priv->spin );
if( p_priv->pipes[1] != -1 ) if( p_priv->pipes[1] != -1 )
close( p_priv->pipes[1] ); close( p_priv->pipes[1] );
if( p_priv->pipes[0] != -1 ) if( p_priv->pipes[0] != -1 )
...@@ -405,52 +403,24 @@ error: ...@@ -405,52 +403,24 @@ error:
*/ */
int vlc_object_waitpipe( vlc_object_t *obj ) int vlc_object_waitpipe( vlc_object_t *obj )
{ {
int pfd[2] = { -1, -1 };
vlc_object_internals_t *internals = vlc_internals( obj ); vlc_object_internals_t *internals = vlc_internals( obj );
bool killed = false;
vlc_spin_lock (&internals->spin); vlc_object_lock (obj);
if (internals->pipes[0] == -1) if (internals->pipes[0] == -1)
{ {
/* This can only ever happen if someone killed us without locking: */ /* This can only ever happen if someone killed us without locking: */
assert (internals->pipes[1] == -1); assert (internals->pipes[1] == -1);
vlc_spin_unlock (&internals->spin);
if (pipe (pfd))
return -1;
vlc_spin_lock (&internals->spin);
if (internals->pipes[0] == -1)
{
internals->pipes[0] = pfd[0];
internals->pipes[1] = pfd[1];
pfd[0] = pfd[1] = -1;
}
killed = obj->b_die;
}
vlc_spin_unlock (&internals->spin);
if (killed)
{
/* Race condition: vlc_object_kill() already invoked! */
int fd;
vlc_spin_lock (&internals->spin);
fd = internals->pipes[1];
internals->pipes[1] = -1;
vlc_spin_unlock (&internals->spin);
if (pipe (internals->pipes))
internals->pipes[0] = internals->pipes[1] = -1;
else
if (obj->b_die)
{ /* Race condition: vlc_object_kill() already invoked! */
msg_Dbg (obj, "waitpipe: object already dying"); msg_Dbg (obj, "waitpipe: object already dying");
if (fd != -1) write (internals->pipes[1], &(uint64_t){ 1 }, sizeof (uint64_t));
close (fd);
} }
}
/* Race condition: two threads call pipe() - unlikely */ vlc_object_unlock (obj);
if (pfd[0] != -1)
close (pfd[0]);
if (pfd[1] != -1)
close (pfd[1]);
return internals->pipes[0]; return internals->pipes[0];
} }
...@@ -488,32 +458,35 @@ void __vlc_object_signal_unlocked( vlc_object_t *obj ) ...@@ -488,32 +458,35 @@ void __vlc_object_signal_unlocked( vlc_object_t *obj )
/** /**
* Requests termination of an object. * Requests termination of an object, cancels the object thread, and make the
* If the object is LibVLC, also request to terminate all its children. * object wait pipe (if it exists) readable. Not a cancellation point.
*/ */
void __vlc_object_kill( vlc_object_t *p_this ) void __vlc_object_kill( vlc_object_t *p_this )
{ {
vlc_object_internals_t *priv = vlc_internals( p_this ); vlc_object_internals_t *priv = vlc_internals( p_this );
int fd; int fd = -1;
vlc_thread_cancel( p_this ); vlc_thread_cancel( p_this );
vlc_object_lock( p_this ); vlc_object_lock( p_this );
p_this->b_die = true; if( !p_this->b_die )
vlc_spin_lock (&priv->spin);
fd = priv->pipes[1];
priv->pipes[1] = -1;
vlc_spin_unlock (&priv->spin);
if( fd != -1 )
{ {
msg_Dbg (p_this, "waitpipe: object killed"); fd = priv->pipes[1];
close_nocancel (fd); p_this->b_die = true;
} }
vlc_cond_broadcast (&priv->wait); vlc_cond_broadcast (&priv->wait);
/* This also serves as a memory barrier toward vlc_object_alive(): */ /* This also serves as a memory barrier toward vlc_object_alive(): */
vlc_object_unlock( p_this ); vlc_object_unlock( p_this );
if (fd != -1)
{
int canc = vlc_savecancel ();
/* write _after_ setting b_die, so vlc_object_alive() returns false */
write (fd, &(uint64_t){ 1 }, sizeof (uint64_t));
msg_Dbg (p_this, "waitpipe: object killed");
vlc_restorecancel (canc);
}
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment