diff --git a/src/xviewer-list-store.c b/src/xviewer-list-store.c index 04603ec..9f89139 100644 --- a/src/xviewer-list-store.c +++ b/src/xviewer-list-store.c @@ -50,6 +50,8 @@ xviewer_list_store_dispose (GObject *object) { XviewerListStore *store = XVIEWER_LIST_STORE (object); + g_mutex_lock (&store->priv->mutex); + g_list_foreach (store->priv->monitors, foreach_monitors_free, NULL); @@ -67,6 +69,8 @@ xviewer_list_store_dispose (GObject *object) store->priv->missing_image = NULL; } + g_mutex_unlock (&store->priv->mutex); + G_OBJECT_CLASS (xviewer_list_store_parent_class)->dispose (object); } @@ -203,6 +207,9 @@ is_file_in_list_store (XviewerListStore *store, gchar *str; GtkTreeIter iter; + // mutex is auto unlocked if this goes out of scope + g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&store->priv->mutex); + if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { return FALSE; } @@ -319,6 +326,7 @@ xviewer_list_store_remove (XviewerListStore *store, GtkTreeIter *iter) { XviewerImage *image; + g_mutex_lock (&store->priv->mutex); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, XVIEWER_LIST_STORE_XVIEWER_IMAGE, &image, -1); @@ -327,6 +335,8 @@ xviewer_list_store_remove (XviewerListStore *store, GtkTreeIter *iter) g_object_unref (image); gtk_list_store_remove (GTK_LIST_STORE (store), iter); + + g_mutex_unlock (&store->priv->mutex); } /** @@ -343,9 +353,11 @@ xviewer_list_store_append_image (XviewerListStore *store, XviewerImage *image) { GtkTreeIter iter; + g_mutex_lock (&store->priv->mutex); + g_signal_connect (image, "changed", - G_CALLBACK (on_image_changed), - store); + G_CALLBACK (on_image_changed), + store); gtk_list_store_append (GTK_LIST_STORE (store), &iter); gtk_list_store_set (GTK_LIST_STORE (store), &iter, @@ -353,6 +365,8 @@ xviewer_list_store_append_image (XviewerListStore *store, XviewerImage *image) XVIEWER_LIST_STORE_THUMBNAIL, store->priv->busy_image, XVIEWER_LIST_STORE_THUMB_SET, FALSE, -1); + + g_mutex_unlock (&store->priv->mutex); } static void @@ -500,6 +514,7 @@ xviewer_list_store_set_directory_callbacks (XviewerListStore *store, 0, NULL, NULL); if (file_monitor != NULL) { + g_mutex_lock (&store->priv->mutex); if (g_list_find(store->priv->monitors, file_monitor) == NULL) { g_signal_connect (file_monitor, "changed", G_CALLBACK (file_monitor_changed_cb), store); @@ -508,6 +523,7 @@ xviewer_list_store_set_directory_callbacks (XviewerListStore *store, to be sorted */ store->priv->monitors = g_list_prepend (store->priv->monitors, file_monitor); } + g_mutex_unlock (&store->priv->mutex); } } @@ -576,9 +592,11 @@ xviewer_list_store_add_files (XviewerListStore *store, GList *file_list) sort_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID; } + g_mutex_lock (&store->priv->mutex); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), sort_id, GTK_SORT_ASCENDING); + g_mutex_unlock (&store->priv->mutex); for (it = file_list; it != NULL; it = it->next) { GFile *file = (GFile *) it->data; @@ -609,9 +627,11 @@ xviewer_list_store_add_files (XviewerListStore *store, GList *file_list) if (sort_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID) { // Given file order isn't conclusive, re-sort in default order. sort_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID; + g_mutex_lock (&store->priv->mutex); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), sort_id, GTK_SORT_ASCENDING); + g_mutex_unlock (&store->priv->mutex); } xviewer_list_store_append_directory (store, file, file_type); } else if (file_type == G_FILE_TYPE_REGULAR && singleton_list) { @@ -636,14 +656,20 @@ xviewer_list_store_add_files (XviewerListStore *store, GList *file_list) if (!is_file_in_list_store_file (store, initial_file, &iter)) { + g_mutex_lock (&store->priv->mutex); xviewer_list_store_append_image_from_file (store, initial_file); + g_mutex_unlock (&store->priv->mutex); } } else { + g_mutex_lock (&store->priv->mutex); xviewer_list_store_append_image_from_file (store, initial_file); + g_mutex_unlock (&store->priv->mutex); } g_object_unref (file); } else if (file_type == G_FILE_TYPE_REGULAR && !singleton_list) { + g_mutex_lock (&store->priv->mutex); xviewer_list_store_append_image_from_file (store, file); + g_mutex_unlock (&store->priv->mutex); g_object_unref (file); @@ -739,6 +765,7 @@ xviewer_list_store_new_from_glist (GList *list) GtkListStore *store = xviewer_list_store_new (); + // no mutex lock required, as this can not be accesed by another thread yet for (it = list; it != NULL; it = it->next) { xviewer_list_store_append_image (XVIEWER_LIST_STORE (store), XVIEWER_IMAGE (it->data)); @@ -796,11 +823,13 @@ xviewer_list_store_get_image_by_pos (XviewerListStore *store, gint pos) g_return_val_if_fail (XVIEWER_IS_LIST_STORE (store), NULL); + g_mutex_lock (&store->priv->mutex); if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, NULL, pos)) { gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, XVIEWER_LIST_STORE_XVIEWER_IMAGE, &image, -1); } + g_mutex_unlock (&store->priv->mutex); return image; } @@ -822,10 +851,12 @@ xviewer_list_store_get_pos_by_iter (XviewerListStore *store, GtkTreePath *path; gint pos; + g_mutex_lock (&store->priv->mutex); path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); indices = gtk_tree_path_get_indices (path); pos = indices [0]; gtk_tree_path_free (path); + g_mutex_unlock (&store->priv->mutex); return pos; } @@ -843,7 +874,10 @@ xviewer_list_store_length (XviewerListStore *store) { g_return_val_if_fail (XVIEWER_IS_LIST_STORE (store), -1); - return gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL); + g_mutex_lock (&store->priv->mutex); + gint length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL); + g_mutex_unlock (&store->priv->mutex); + return length; } /** @@ -870,20 +904,18 @@ xviewer_list_store_remove_thumbnail_job (XviewerListStore *store, { XviewerJob *job; + g_mutex_lock (&store->priv->mutex); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, XVIEWER_LIST_STORE_XVIEWER_JOB, &job, -1); if (job != NULL) { - g_mutex_lock (&store->priv->mutex); xviewer_job_cancel (job); gtk_list_store_set (GTK_LIST_STORE (store), iter, XVIEWER_LIST_STORE_XVIEWER_JOB, NULL, -1); - g_mutex_unlock (&store->priv->mutex); } - - + g_mutex_unlock (&store->priv->mutex); } static void @@ -892,10 +924,12 @@ xviewer_list_store_add_thumbnail_job (XviewerListStore *store, GtkTreeIter *iter XviewerImage *image; XviewerJob *job; + g_mutex_lock (&store->priv->mutex); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, XVIEWER_LIST_STORE_XVIEWER_IMAGE, &image, XVIEWER_LIST_STORE_XVIEWER_JOB, &job, -1); + g_mutex_unlock (&store->priv->mutex); if (job != NULL) { g_object_unref (image); @@ -933,9 +967,11 @@ xviewer_list_store_thumbnail_set (XviewerListStore *store, { gboolean thumb_set = FALSE; + g_mutex_lock (&store->priv->mutex); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, XVIEWER_LIST_STORE_THUMB_SET, &thumb_set, -1); + g_mutex_unlock (&store->priv->mutex); if (thumb_set) { return; @@ -961,16 +997,21 @@ xviewer_list_store_thumbnail_unset (XviewerListStore *store, xviewer_list_store_remove_thumbnail_job (store, iter); + g_mutex_lock (&store->priv->mutex); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, XVIEWER_LIST_STORE_XVIEWER_IMAGE, &image, -1); + g_mutex_unlock (&store->priv->mutex); + xviewer_image_set_thumbnail (image, NULL); g_object_unref (image); + g_mutex_lock (&store->priv->mutex); gtk_list_store_set (GTK_LIST_STORE (store), iter, XVIEWER_LIST_STORE_THUMBNAIL, store->priv->busy_image, XVIEWER_LIST_STORE_THUMB_SET, FALSE, -1); + g_mutex_unlock (&store->priv->mutex); } /**