From 24298341eb3b322f6f4eba55ff8b58399890c72e Mon Sep 17 00:00:00 2001
From: Pierre d'Herbemont <pdherbemont@videolan.org>
Date: Sun, 6 Jul 2008 12:46:04 +0200
Subject: [PATCH] playlist: Make sure we don't crash when we delete the
 currently playing node.

---
 src/playlist/control.c | 14 ++++++++++++++
 src/playlist/engine.c  |  9 +++++++++
 src/playlist/tree.c    | 19 ++++++++++++++++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/playlist/control.c b/src/playlist/control.c
index 2f22476c54..fa2644cc16 100644
--- a/src/playlist/control.c
+++ b/src/playlist/control.c
@@ -373,9 +373,23 @@ playlist_item_t * playlist_NextItem( playlist_t *p_playlist )
                         PLI_NAME( p_playlist->request.p_item ),
                         PLI_NAME( p_playlist->request.p_node ), i_skip );
 
+        /* Make sure the node wasn't deleted */
+        if( p_playlist->status.p_node &&
+            p_playlist->status.p_node->i_flags & PLAYLIST_REMOVE_FLAG )
+        {
+             PL_DEBUG( "%s was marked for deletion, deleting",
+                             PLI_NAME( p_playlist->status.p_node  ) );
+             playlist_ItemDelete( p_playlist->status.p_node );
+             /* Don't attempt to reuse that node */
+             if( p_playlist->status.p_node == p_playlist->request.p_node )
+                p_playlist->request.p_node = NULL;
+             p_playlist->status.p_node = NULL;
+        }
+
         if( p_playlist->request.p_node &&
             p_playlist->request.p_node != p_playlist->status.p_node )
         {
+
             p_playlist->status.p_node = p_playlist->request.p_node;
             p_playlist->b_reset_currently_playing = true;
         }
diff --git a/src/playlist/engine.c b/src/playlist/engine.c
index f6385d01e3..3631c1fb58 100644
--- a/src/playlist/engine.c
+++ b/src/playlist/engine.c
@@ -477,6 +477,15 @@ void playlist_LastLoop( playlist_t *p_playlist )
         sout_DeleteInstance( p_sout );
 #endif
 
+    if( p_playlist->status.p_node &&
+        p_playlist->status.p_node->i_flags & PLAYLIST_REMOVE_FLAG )
+    {
+         PL_DEBUG( "%s was marked for deletion, deleting",
+                         PLI_NAME( p_playlist->status.p_node  ) );
+         playlist_ItemDelete( p_playlist->status.p_node );
+         p_playlist->status.p_node = NULL;
+    }
+
     /* Core should have terminated all SDs before the playlist */
     /* TODO: It fails to do so when not playing anything -- Courmisch */
     playlist_ServicesDiscoveryKillAll( p_playlist );
diff --git a/src/playlist/tree.c b/src/playlist/tree.c
index c10451817d..35eb33b367 100644
--- a/src/playlist/tree.c
+++ b/src/playlist/tree.c
@@ -171,7 +171,24 @@ int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
         if( p_root->p_parent )
             playlist_NodeRemoveItem( p_playlist, p_root, p_root->p_parent );
 
-        playlist_ItemDelete( p_root );
+        /* Check if it is the current node */
+        if( p_playlist->status.p_node == p_root )
+        {
+            /* Hack we don't call playlist_Control for lock reasons */
+            p_playlist->request.i_status = PLAYLIST_STOPPED;
+            p_playlist->request.b_request = true;
+            p_playlist->request.p_item = NULL;
+            p_playlist->request.p_node = NULL;
+            msg_Info( p_playlist, "stopping playback" );
+            vlc_object_signal_maybe( VLC_OBJECT(p_playlist) );
+
+            PL_DEBUG( "marking %s for further deletion", PLI_NAME( p_root ) );
+            p_root->i_flags |= PLAYLIST_REMOVE_FLAG;
+        }
+        else
+            playlist_ItemDelete( p_root );
+
+
     }
     return VLC_SUCCESS;
 }
-- 
2.25.4