]> git.sesse.net Git - vlc/commitdiff
Allow vlc_object_attach to reparent directly
authorRémi Denis-Courmont <remi@remlab.net>
Thu, 28 Jan 2010 20:09:39 +0000 (22:09 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Thu, 28 Jan 2010 20:09:39 +0000 (22:09 +0200)
This saves one unlock/lock cycle, and makes sure that the reparented
object remains in the tree at all times. This does not fix the race in
reparenting, but it reduces its window of opportunity.

This also makes vlc_object_detach() essentially redumdant with
vlc_object_release() and vlc_object_attach().

src/misc/objects.c

index fb1dc399b4104f3e5fbb0fbb23107e37fa20394f..725f10b6a09b6a516f3d5f901bc01c6276498beb 100644 (file)
@@ -611,6 +611,7 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
 
     vlc_object_internals_t *pap = vlc_internals (p_parent);
     vlc_object_internals_t *priv = vlc_internals (p_this);
+    vlc_object_t *p_old_parent;
 
     priv->prev = NULL;
     vlc_object_hold (p_parent);
@@ -630,8 +631,11 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
                   priv->old_parent, p_parent);
 #endif
 
+    p_old_parent = p_this->p_parent;
+    if (p_old_parent)
+        vlc_object_detach_unlocked (p_this);
+
     /* Attach the parent to its child */
-    assert (!p_this->p_parent);
     p_this->p_parent = p_parent;
 
     /* Attach the child to its parent */
@@ -640,6 +644,9 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
         priv->next->prev = priv;
     pap->first = priv;
     libvlc_unlock (p_this->p_libvlc);
+
+    if (p_old_parent)
+        vlc_object_release (p_old_parent);
 }