Commit 89e10b6c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

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.
parent 69022122
...@@ -954,15 +954,18 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) ...@@ -954,15 +954,18 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
} }
#endif #endif
playlist_t *p_playlist = priv->p_playlist;
/* Remove all services discovery */ /* Remove all services discovery */
msg_Dbg( p_libvlc, "removing all services discovery tasks" ); msg_Dbg( p_libvlc, "removing all services discovery tasks" );
playlist_ServicesDiscoveryKillAll( priv->p_playlist ); playlist_ServicesDiscoveryKillAll( p_playlist );
/* Free playlist */ /* Free playlist */
/* Any thread still running must not assume pl_Yield() succeeds. */
msg_Dbg( p_libvlc, "removing playlist" ); msg_Dbg( p_libvlc, "removing playlist" );
vlc_object_kill( priv->p_playlist ); priv->p_playlist = NULL;
vlc_thread_join( priv->p_playlist ); vlc_object_kill( p_playlist ); /* <-- memory barrier for pl_Yield() */
vlc_object_release( priv->p_playlist ); vlc_thread_join( p_playlist );
vlc_object_release( p_playlist );
/* Free interaction */ /* Free interaction */
msg_Dbg( p_libvlc, "removing interaction" ); msg_Dbg( p_libvlc, "removing interaction" );
......
...@@ -43,14 +43,12 @@ static void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * ); ...@@ -43,14 +43,12 @@ static void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
playlist_t *__pl_Yield( vlc_object_t *p_this ) playlist_t *__pl_Yield( vlc_object_t *p_this )
{ {
playlist_t *pl = libvlc_priv (p_this->p_libvlc)->p_playlist; playlist_t *pl;
/* 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);
assert( pl != NULL ); barrier ();
vlc_object_yield( pl ); pl = libvlc_priv (p_this->p_libvlc)->p_playlist;
if (pl)
vlc_object_yield (pl);
return pl; return pl;
} }
......
...@@ -173,9 +173,6 @@ static void playlist_Destructor( vlc_object_t * p_this ) ...@@ -173,9 +173,6 @@ static void playlist_Destructor( vlc_object_t * p_this )
if( p_playlist->p_fetcher ) if( p_playlist->p_fetcher )
vlc_object_release( 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 */ /* Destroy remaining objects */
......
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