>From 4e12f363df232681c569790fe56f57dde010a73b Mon Sep 17 00:00:00 2001 From: Andreas Winkelmann Date: Mon, 26 May 2014 17:00:59 +0200 Subject: [PATCH 1/3] 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 | 45 +++++++++++++++++++++++++++++++++++++++++---- src/browser.h | 4 ++++ src/et_core.c | 11 +++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/browser.c b/src/browser.c index 3027ec5..07611c7 100644 --- a/src/browser.c +++ b/src/browser.c @@ -1736,8 +1736,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_List_Clear(); + Browser_Album_List_Clear(); } @@ -1968,6 +1968,24 @@ void Browser_List_Invert_File_Selection (void) } } +void Browser_Artist_List_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(G_OBJECT(selection),G_CALLBACK(Browser_Artist_List_Row_Selected),NULL); + + gtk_list_store_clear( artistListModel ); + + g_signal_handlers_unblock_by_func(G_OBJECT(selection),G_CALLBACK(Browser_Artist_List_Row_Selected),NULL); + +} void Browser_Artist_List_Load_Files (ET_File *etfile_to_select) { @@ -1985,7 +2003,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_List_Clear(); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(BrowserArtistList)); for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l)) @@ -2117,7 +2136,24 @@ Browser_Artist_List_Set_Row_Appearance (GtkTreeIter *iter) } } +void Browser_Album_List_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(G_OBJECT(selection),G_CALLBACK(Browser_Album_List_Row_Selected),NULL); + + gtk_list_store_clear( albumListModel ); + + g_signal_handlers_unblock_by_func(G_OBJECT(selection),G_CALLBACK(Browser_Album_List_Row_Selected),NULL); + +} /* * Load the list of Albums for each Artist @@ -2137,7 +2173,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_List_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..3560caf 100644 --- a/src/browser.h +++ b/src/browser.h @@ -143,6 +143,10 @@ GtkWidget *RenameDirectoryPreviewLabel; **************/ GtkWidget *Create_Browser_Items (GtkWidget *parent); + +void Browser_Album_List_Clear( void ); +void Browser_Artist_List_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..dc2d8a3 100644 --- a/src/et_core.c +++ b/src/et_core.c @@ -2390,6 +2390,17 @@ 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_List_Clear(); + Browser_Album_List_Clear(); + + /* + * Now clear the list + */ + for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l)) { GList *m; -- 1.8.4.5