]> git.sesse.net Git - vlc/blobdiff - src/misc/objects.c
Fix deadlock in vlc_object_kill (should fix #1543)
[vlc] / src / misc / objects.c
index 9cea38cd136b971fa2d58247f45d371c8afbbe95..325c55712cb00ee6c36009259a00f95543e56864 100644 (file)
@@ -176,8 +176,8 @@ void *vlc_custom_create( vlc_object_t *p_this, size_t i_size,
     p_new->p_private = NULL;
 
     /* Initialize mutexes and condvars */
-    vlc_mutex_init( &p_new->object_lock );
-    vlc_cond_init( p_new, &p_new->object_wait );
+    vlc_mutex_init( &p_priv->lock );
+    vlc_cond_init( p_new, &p_priv->wait );
     vlc_mutex_init( &p_priv->var_lock );
     vlc_spin_init( &p_priv->spin );
     p_priv->pipes[0] = p_priv->pipes[1] = -1;
@@ -270,10 +270,6 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             i_size = sizeof( announce_handler_t );
             psz_type = "announce";
             break;
-        case VLC_OBJECT_INTERACTION:
-            i_size = sizeof( interaction_t );
-            psz_type = "interaction";
-            break;
         default:
             i_size = i_type > (int)sizeof(vlc_object_t)
                          ? i_type : (int)sizeof(vlc_object_t);
@@ -387,8 +383,8 @@ static void vlc_object_destroy( vlc_object_t *p_this )
 #endif
 
     vlc_spin_destroy( &p_priv->ref_spin );
-    vlc_mutex_destroy( &p_this->object_lock );
-    vlc_cond_destroy( &p_this->object_wait );
+    vlc_mutex_destroy( &p_priv->lock );
+    vlc_cond_destroy( &p_priv->wait );
     vlc_spin_destroy( &p_priv->spin );
     if( p_priv->pipes[1] != -1 )
         close( p_priv->pipes[1] );
@@ -403,13 +399,13 @@ static void vlc_object_destroy( vlc_object_t *p_this )
 
 void __vlc_object_lock( vlc_object_t *obj )
 {
-    vlc_mutex_lock( &obj->object_lock );
+    vlc_mutex_lock( &(vlc_internals(obj)->lock) );
 }
 
 void __vlc_object_unlock( vlc_object_t *obj )
 {
-    vlc_assert_locked( &obj->object_lock );
-    vlc_mutex_unlock( &obj->object_lock );
+    vlc_assert_locked( &(vlc_internals(obj)->lock) );
+    vlc_mutex_unlock( &(vlc_internals(obj)->lock) );
 }
 
 #ifdef WIN32
@@ -540,8 +536,9 @@ int __vlc_object_waitpipe( vlc_object_t *obj )
  */
 void __vlc_object_wait( vlc_object_t *obj )
 {
-    vlc_assert_locked( &obj->object_lock );
-    vlc_cond_wait( &obj->object_wait, &obj->object_lock );
+    vlc_object_internals_t *priv = vlc_internals( obj );
+    vlc_assert_locked( &priv->lock);
+    vlc_cond_wait( &priv->wait, &priv->lock );
 }
 
 
@@ -554,8 +551,9 @@ void __vlc_object_wait( vlc_object_t *obj )
  */
 int __vlc_object_timedwait( vlc_object_t *obj, mtime_t deadline )
 {
-    vlc_assert_locked( &obj->object_lock );
-    return vlc_cond_timedwait( &obj->object_wait, &obj->object_lock, deadline );
+    vlc_object_internals_t *priv = vlc_internals( obj );
+    vlc_assert_locked( &priv->lock);
+    return vlc_cond_timedwait( &priv->wait, &priv->lock, deadline );
 }
 
 
@@ -583,7 +581,7 @@ int __vlc_object_timedwait( vlc_object_t *obj, mtime_t deadline )
  */
 bool __vlc_object_alive( vlc_object_t *obj )
 {
-    vlc_assert_locked( &obj->object_lock );
+    vlc_assert_locked( &(vlc_internals(obj)->lock) );
     return !obj->b_die;
 }
 
@@ -597,8 +595,8 @@ bool __vlc_object_alive( vlc_object_t *obj )
  */
 void __vlc_object_signal_unlocked( vlc_object_t *obj )
 {
-    vlc_assert_locked (&obj->object_lock);
-    vlc_cond_signal( &obj->object_wait );
+    vlc_assert_locked (&(vlc_internals(obj)->lock));
+    vlc_cond_signal( &(vlc_internals(obj)->wait) );
 }
 
 
@@ -608,16 +606,16 @@ void __vlc_object_signal_unlocked( vlc_object_t *obj )
  */
 void __vlc_object_kill( vlc_object_t *p_this )
 {
-    vlc_object_internals_t *internals = vlc_internals( p_this );
+    vlc_object_internals_t *priv = vlc_internals( p_this );
     int fd;
 
-    vlc_mutex_lock( &p_this->object_lock );
+    vlc_object_lock( p_this );
     p_this->b_die = true;
 
-    vlc_spin_lock (&internals->spin);
-    fd = internals->pipes[1];
-    internals->pipes[1] = -1;
-    vlc_spin_unlock (&internals->spin);
+    vlc_spin_lock (&priv->spin);
+    fd = priv->pipes[1];
+    priv->pipes[1] = -1;
+    vlc_spin_unlock (&priv->spin);
 
     if( fd != -1 )
     {
@@ -626,14 +624,18 @@ void __vlc_object_kill( vlc_object_t *p_this )
     }
 
     vlc_object_signal_unlocked( p_this );
-    vlc_mutex_unlock( &p_this->object_lock );
+    vlc_object_unlock( p_this );
 
     if (p_this->i_object_type == VLC_OBJECT_LIBVLC)
     {
-        vlc_list_t *children = vlc_list_children (p_this);
-        for (int i = 0; i < children->i_count; i++)
-            vlc_object_kill (children->p_values[i].p_object);
-        vlc_list_release (children);
+        /* Do not use vlc_list_children() here! We don't want to yield/release
+         * all the children of LibVLC (-> dead lock). This is a hack anyway:
+         * LibVLC should kill its children by itself as it sees fit, as any
+         * other object. */
+        vlc_mutex_lock (&structure_lock);
+        for (int i = 0; i < priv->i_children; i++)
+            vlc_object_kill (priv->pp_children[i]);
+        vlc_mutex_unlock (&structure_lock);
     }
 }