]> git.sesse.net Git - vlc/commitdiff
pl_Yield(): return NULL when the playlist is gone (or going)
authorRémi Denis-Courmont <rdenis@simphalempin.com>
Sat, 5 Jul 2008 14:29:04 +0000 (17:29 +0300)
committerRémi Denis-Courmont <rdenis@simphalempin.com>
Sat, 5 Jul 2008 14:29:04 +0000 (17:29 +0300)
This allows using pl_Yield() from video outputs and friends, on
condition that pl_Yield() return value be checked for NULLity.

Should fix #1667.

src/libvlc.c
src/playlist/control.c
src/playlist/engine.c

index e16c14ce413f9b4bb35ece2d9ce4910effe8a5ba..755438b011a6e31ca5ff6e0043ec4622fd204abf 100644 (file)
@@ -954,15 +954,18 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
     }
 #endif
 
+    playlist_t *p_playlist = priv->p_playlist;
     /* Remove all services discovery */
     msg_Dbg( p_libvlc, "removing all services discovery tasks" );
-    playlist_ServicesDiscoveryKillAll( priv->p_playlist );
+    playlist_ServicesDiscoveryKillAll( p_playlist );
 
     /* Free playlist */
+    /* Any thread still running must not assume pl_Yield() succeeds. */
     msg_Dbg( p_libvlc, "removing playlist" );
-    vlc_object_kill( priv->p_playlist );
-    vlc_thread_join( priv->p_playlist );
-    vlc_object_release( priv->p_playlist );
+    priv->p_playlist = NULL;
+    vlc_object_kill( p_playlist ); /* <-- memory barrier for pl_Yield() */
+    vlc_thread_join( p_playlist );
+    vlc_object_release( p_playlist );
 
     /* Free interaction */
     msg_Dbg( p_libvlc, "removing interaction" );
index 1ada1204c9684847b13165390cb9e01c72c176d9..2f22476c544568a8625d130c0f2091408dfb4c46 100644 (file)
@@ -43,14 +43,12 @@ static void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
 
 playlist_t *__pl_Yield( vlc_object_t *p_this )
 {
-    playlist_t *pl = libvlc_priv (p_this->p_libvlc)->p_playlist;
-    /* Objects that are destroyed _after_ the playlist cannot use pl_Yield() */
-    assert (p_this->i_object_type != VLC_OBJECT_VOUT);
-    assert (p_this->i_object_type != VLC_OBJECT_ANNOUNCE);
-    assert ((void *)p_this != libvlc_priv (p_this->p_libvlc)->p_interaction);
+    playlist_t *pl;
 
-    assert( pl != NULL );
-    vlc_object_yield( pl );
+    barrier ();
+    pl = libvlc_priv (p_this->p_libvlc)->p_playlist;
+    if (pl)
+        vlc_object_yield (pl);
     return pl;
 }
 
index ed909a837b4a4061636ef1a361473158ea647900..f6385d01e3a83f63e0d750f3f1ef4270aa39b50a 100644 (file)
@@ -173,9 +173,6 @@ static void playlist_Destructor( vlc_object_t * p_this )
 
     if( p_playlist->p_fetcher )
         vlc_object_release( p_playlist->p_fetcher );
-#ifndef NDEBUG
-    libvlc_priv (p_this->p_libvlc)->p_playlist = NULL; /* pl_Yield() will fail */
-#endif
 }
 
 /* Destroy remaining objects */