[vlc-devel] commit: pl_Yield(): return NULL when the playlist is gone (or going) ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sat Jul 5 16:28:01 CEST 2008
vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Sat Jul 5 17:29:04 2008 +0300| [89e10b6c29b7b18ad251b2f55da95a961d54a554]
pl_Yield(): return NULL when the playlist is gone (or going)
This allows using pl_Yield() from video outputs and friends, on
condition that pl_Yield() return value be checked for NULLity.
Should fix #1667.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=89e10b6c29b7b18ad251b2f55da95a961d54a554
---
src/libvlc.c | 11 +++++++----
src/playlist/control.c | 12 +++++-------
src/playlist/engine.c | 3 ---
3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/src/libvlc.c b/src/libvlc.c
index e16c14c..755438b 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -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" );
diff --git a/src/playlist/control.c b/src/playlist/control.c
index 1ada120..2f22476 100644
--- a/src/playlist/control.c
+++ b/src/playlist/control.c
@@ -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;
}
diff --git a/src/playlist/engine.c b/src/playlist/engine.c
index ed909a8..f6385d0 100644
--- a/src/playlist/engine.c
+++ b/src/playlist/engine.c
@@ -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 */
More information about the vlc-devel
mailing list