[easytag/wip/awinkelmann: 1/2] Fixed a few crashes because of dangling pointers



commit 984add235de356aaa527d1a7d85f1a862b3d7b0a
Author: Andreas Winkelmann <ml awinkelmann de>
Date:   Mon May 26 17:00:59 2014 +0200

    Fixed a few crashes because of dangling pointers
    
    The two List-Stores from the Artist/Album View contain Pointers to the
    List in ETCore->ETArtistAlbumFileList. When the complete List was freed,
    the GUI still used the Pointers in the List-Stores and crashed.
    
    I saw Segmentation Faults while toggeling between ArtistAlbum and
    Directory-View and furthermore while shutting down ET.

 src/browser.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/browser.h |    4 ++++
 src/et_core.c |    5 +++++
 3 files changed, 55 insertions(+), 4 deletions(-)
---
diff --git a/src/browser.c b/src/browser.c
index 83ef596..97e0227 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -1732,8 +1732,8 @@ ET_File *Browser_List_Select_File_By_DLM (const gchar* string, gboolean select_i
 void Browser_List_Clear()
 {
     gtk_list_store_clear(fileListModel);
-    gtk_list_store_clear(artistListModel);
-    gtk_list_store_clear(albumListModel);
+    browser_artist_model_clear ();
+    browser_album_model_clear ();
 
 }
 
@@ -1964,6 +1964,27 @@ void Browser_List_Invert_File_Selection (void)
     }
 }
 
+void
+browser_artist_model_clear (void)
+{
+    GtkTreeSelection *selection;
+
+    /* Empty Model, Disable Browser_Artist_List_Row_Selected() during clear
+     * because it may be called and may crash.
+    */
+
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (BrowserArtistList));
+
+    g_signal_handlers_block_by_func (selection,
+                                     G_CALLBACK (Browser_Artist_List_Row_Selected),
+                                     NULL);
+
+    gtk_list_store_clear (artistListModel);
+
+    g_signal_handlers_unblock_by_func (selection,
+                                       G_CALLBACK (Browser_Artist_List_Row_Selected),
+                                       NULL);
+}
 
 void Browser_Artist_List_Load_Files (ET_File *etfile_to_select)
 {
@@ -1981,7 +2002,8 @@ void Browser_Artist_List_Load_Files (ET_File *etfile_to_select)
     if (etfile_to_select)
         artist_to_select = ((File_Tag *)etfile_to_select->FileTag->data)->artist;
 
-    gtk_list_store_clear(artistListModel);
+    browser_artist_model_clear ();
+
     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(BrowserArtistList));
 
     for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l))
@@ -2113,7 +2135,26 @@ Browser_Artist_List_Set_Row_Appearance (GtkTreeIter *iter)
     }
 }
 
+void
+browser_album_model_clear (void)
+{
+    GtkTreeSelection *selection;
+
+    /* Empty model, disable Browser_Album_List_Row_Selected () during clear
+     * because it is called and crashed. */
+
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (BrowserAlbumList));
 
+    g_signal_handlers_block_by_func (selection,
+                                     G_CALLBACK (Browser_Album_List_Row_Selected),
+                                     NULL);
+
+    gtk_list_store_clear (albumListModel);
+
+    g_signal_handlers_unblock_by_func (selection,
+                                       G_CALLBACK (Browser_Album_List_Row_Selected),
+                                       NULL);
+}
 
 /*
  * Load the list of Albums for each Artist
@@ -2133,7 +2174,8 @@ Browser_Album_List_Load_Files (GList *albumlist, ET_File *etfile_to_select)
     if (etfile_to_select)
         album_to_select = ((File_Tag *)etfile_to_select->FileTag->data)->album;
 
-    gtk_list_store_clear(albumListModel);
+    browser_album_model_clear ();
+
     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(BrowserAlbumList));
 
     // Create a first row to select all albums of the artist
diff --git a/src/browser.h b/src/browser.h
index 5965379..db6850c 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -143,6 +143,10 @@ GtkWidget *RenameDirectoryPreviewLabel;
  **************/
 
 GtkWidget   *Create_Browser_Items    (GtkWidget *parent);
+
+void browser_album_model_clear (void);
+void browser_artist_model_clear (void);
+
 gboolean     Browser_Tree_Select_Dir (const gchar *current_path);
 void         Browser_Tree_Rebuild    (gchar *path_to_load);
 void         Browser_Tree_Collapse   (void);
diff --git a/src/et_core.c b/src/et_core.c
index fe4554d..b278494 100644
--- a/src/et_core.c
+++ b/src/et_core.c
@@ -2390,6 +2390,11 @@ ET_Free_Artist_Album_File_List (void)
     g_return_val_if_fail (ETCore != NULL
                           && ETCore->ETArtistAlbumFileList != NULL, FALSE);
 
+    /* Pointers are stored inside the artist/album list-stores, so free them
+     * first. */
+    browser_artist_model_clear ();
+    browser_album_model_clear ();
+
     for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l))
     {
         GList *m;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]