From 3209febd7ac7abf4d172988b63cd3f3b54394b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Tue, 25 Feb 2025 21:05:35 +0100 Subject: [PATCH 1/6] MessageList: Replace g_idle_add with idle source attached to the task Makes the GTask lifetime easier to understand. --- src/mail/message-list.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index 2bc66964e4..9421f0f80a 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -86,7 +86,7 @@ struct _MessageListPrivate { /* For message list regeneration. */ GMutex regen_lock; RegenData *regen_data; - guint regen_idle_id; + GSource *regen_idle_source; gboolean thaw_needs_regen; @@ -3476,7 +3476,7 @@ message_list_dispose (GObject *object) g_mutex_lock (&message_list->priv->regen_lock); - /* This can happen when the regen_idle_id is removed before it's invoked */ + /* This can happen when the regen_idle_source is removed before it's invoked */ g_clear_pointer (&message_list->priv->regen_data, regen_data_unref); g_mutex_unlock (&message_list->priv->regen_lock); @@ -7026,7 +7026,7 @@ message_list_regen_idle_cb (gpointer user_data) regen_data->expand_state = e_tree_table_adapter_save_expanded_state_xml (adapter); } - message_list->priv->regen_idle_id = 0; + g_clear_pointer (&message_list->priv->regen_idle_source, g_source_unref); g_mutex_unlock (&message_list->priv->regen_lock); @@ -7046,9 +7046,9 @@ mail_regen_cancel (MessageList *message_list) if (message_list->priv->regen_data != NULL) regen_data = regen_data_ref (message_list->priv->regen_data); - if (message_list->priv->regen_idle_id > 0) { - g_source_remove (message_list->priv->regen_idle_id); - message_list->priv->regen_idle_id = 0; + if (message_list->priv->regen_idle_source) { + g_source_destroy (message_list->priv->regen_idle_source); + g_clear_pointer (&message_list->priv->regen_idle_source, g_source_unref); } g_mutex_unlock (&message_list->priv->regen_lock); @@ -7106,7 +7106,7 @@ mail_regen_list (MessageList *message_list, /* If a regen is scheduled but not yet started, just * apply the argument values without cancelling it. */ - if (message_list->priv->regen_idle_id > 0) { + if (message_list->priv->regen_idle_source) { g_return_if_fail (old_regen_data != NULL); if (g_strcmp0 (search, old_regen_data->search) != 0) { @@ -7170,17 +7170,15 @@ mail_regen_list (MessageList *message_list, * MessageList changes without triggering additional regens. */ message_list->priv->regen_data = regen_data_ref (new_regen_data); - - message_list->priv->regen_idle_id = - g_idle_add_full ( - G_PRIORITY_DEFAULT_IDLE, - message_list_regen_idle_cb, - g_steal_pointer (&task), - (GDestroyNotify) g_object_unref); + message_list->priv->regen_idle_source = g_idle_source_new (); + g_task_attach_source (task, + message_list->priv->regen_idle_source, + message_list_regen_idle_cb); regen_data_unref (new_regen_data); g_object_unref (cancellable); + g_object_unref (task); exit: g_mutex_unlock (&message_list->priv->regen_lock); -- GitLab From a135215f8020ee9b1630d80dfc735ea7bea193d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Wed, 26 Feb 2025 08:40:51 +0100 Subject: [PATCH 2/6] MessageList: Get rid of message_list_ref_regen_data Just acquire the mutex to access the regen_data, no need to increase its reference. --- src/mail/message-list.c | 71 ++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 44 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index 9421f0f80a..d772c3d27f 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -565,21 +565,6 @@ regen_data_unref (RegenData *regen_data) } } -static RegenData * -message_list_ref_regen_data (MessageList *message_list) -{ - RegenData *regen_data = NULL; - - g_mutex_lock (&message_list->priv->regen_lock); - - if (message_list->priv->regen_data != NULL) - regen_data = regen_data_ref (message_list->priv->regen_data); - - g_mutex_unlock (&message_list->priv->regen_lock); - - return regen_data; -} - static void message_list_tree_model_freeze (MessageList *message_list) { @@ -1170,7 +1155,7 @@ message_list_select_uid (MessageList *message_list, MessageListPrivate *priv; GHashTable *uid_nodemap; GNode *node = NULL; - RegenData *regen_data = NULL; + RegenData *regen_data; g_return_if_fail (IS_MESSAGE_LIST (message_list)); @@ -1184,7 +1169,8 @@ message_list_select_uid (MessageList *message_list, if (uid != NULL) node = g_hash_table_lookup (uid_nodemap, uid); - regen_data = message_list_ref_regen_data (message_list); + g_mutex_lock (&message_list->priv->regen_lock); + regen_data = message_list->priv->regen_data; /* If we're busy or waiting to regenerate the message list, cache * the UID so we can try again when we're done. Otherwise if the @@ -1201,8 +1187,6 @@ message_list_select_uid (MessageList *message_list, regen_data->select_use_fallback = with_fallback; g_mutex_unlock (®en_data->select_lock); - regen_data_unref (regen_data); - } else if (with_fallback) { if (node == NULL && priv->oldest_unread_uid != NULL) node = g_hash_table_lookup ( @@ -1212,6 +1196,8 @@ message_list_select_uid (MessageList *message_list, uid_nodemap, priv->newest_read_uid); } + g_mutex_unlock (&message_list->priv->regen_lock); + if (node) { ETree *tree; GNode *old_cur; @@ -1333,11 +1319,12 @@ message_list_select_prev_thread (MessageList *message_list) void message_list_select_all (MessageList *message_list) { - RegenData *regen_data = NULL; + RegenData *regen_data; g_return_if_fail (IS_MESSAGE_LIST (message_list)); - regen_data = message_list_ref_regen_data (message_list); + g_mutex_lock (&message_list->priv->regen_lock); + regen_data = message_list->priv->regen_data; if (regen_data != NULL && regen_data->group_by_threads) { regen_data->select_all = TRUE; @@ -1350,8 +1337,7 @@ message_list_select_all (MessageList *message_list) e_selection_model_select_all (selection_model); } - if (regen_data != NULL) - regen_data_unref (regen_data); + g_mutex_unlock (&message_list->priv->regen_lock); } typedef struct thread_select_info { @@ -5142,7 +5128,7 @@ message_list_folder_changed (CamelFolder *folder, MessageList *message_list) { CamelFolderChangeInfo *altered_changes = NULL; - RegenData *regen_data; + gboolean has_regen_data; gboolean need_list_regen = TRUE; g_return_if_fail (CAMEL_IS_FOLDER (folder)); @@ -5152,11 +5138,13 @@ message_list_folder_changed (CamelFolder *folder, if (message_list->priv->destroyed) return; - regen_data = message_list_ref_regen_data (message_list); + g_mutex_lock (&message_list->priv->regen_lock); + has_regen_data = message_list->priv->regen_data != NULL; + g_mutex_unlock (&message_list->priv->regen_lock); d ( - printf ("%s: regen_data:%p changes:%p added:%d removed:%d changed:%d recent:%d for '%s'\n", - G_STRFUNC, regen_data, changes, + printf ("%s: has_regen_data:%s changes:%p added:%d removed:%d changed:%d recent:%d for '%s'\n", + G_STRFUNC, has_regen_data ? "yes": "no", changes, changes ? changes->uid_added->len : -1, changes ? changes->uid_removed->len : -1, changes ? changes->uid_changed->len : -1, @@ -5164,7 +5152,7 @@ message_list_folder_changed (CamelFolder *folder, camel_folder_get_full_name (folder))); /* Skip the quick update when the message list is being regenerated */ - if (changes && !regen_data) { + if (changes && !has_regen_data) { ETreeModel *tree_model; gboolean hide_junk; gboolean hide_deleted; @@ -5225,9 +5213,6 @@ message_list_folder_changed (CamelFolder *folder, if (altered_changes != NULL) camel_folder_change_info_free (altered_changes); - - if (regen_data) - regen_data_unref (regen_data); } typedef struct _FolderChangedData { @@ -6151,24 +6136,23 @@ void message_list_set_search (MessageList *message_list, const gchar *search) { - RegenData *current_regen_data; + gboolean has_regen_data; g_return_if_fail (IS_MESSAGE_LIST (message_list)); - current_regen_data = message_list_ref_regen_data (message_list); + g_mutex_lock (&message_list->priv->regen_lock); + has_regen_data = message_list->priv->regen_data != NULL; + g_mutex_unlock (&message_list->priv->regen_lock); - if (!current_regen_data && (search == NULL || search[0] == '\0')) + if (!has_regen_data && (search == NULL || search[0] == '\0')) if (message_list->search == NULL || message_list->search[0] == '\0') return; - if (!current_regen_data && search != NULL && message_list->search != NULL && + if (!has_regen_data && search != NULL && message_list->search != NULL && strcmp (search, message_list->search) == 0) { return; } - if (current_regen_data) - regen_data_unref (current_regen_data); - if (message_list->frozen == 0) mail_regen_list (message_list, search ? search : "", NULL); else { @@ -7072,7 +7056,9 @@ mail_regen_list (MessageList *message_list, gchar *tmp_search_copy = NULL; if (!search) { - old_regen_data = message_list_ref_regen_data (message_list); + g_mutex_lock (&message_list->priv->regen_lock); + + old_regen_data = message_list->priv->regen_data; if (old_regen_data && old_regen_data->folder == message_list->priv->folder) { tmp_search_copy = g_strdup (old_regen_data->search); @@ -7082,8 +7068,7 @@ mail_regen_list (MessageList *message_list, search = tmp_search_copy; } - if (old_regen_data) - regen_data_unref (old_regen_data); + g_mutex_unlock (&message_list->priv->regen_lock); } else if (search && !*search) { search = NULL; } @@ -7169,14 +7154,12 @@ mail_regen_list (MessageList *message_list, * the remainder of this main loop iteration to make further * MessageList changes without triggering additional regens. */ - message_list->priv->regen_data = regen_data_ref (new_regen_data); + message_list->priv->regen_data = g_steal_pointer (&new_regen_data); message_list->priv->regen_idle_source = g_idle_source_new (); g_task_attach_source (task, message_list->priv->regen_idle_source, message_list_regen_idle_cb); - regen_data_unref (new_regen_data); - g_object_unref (cancellable); g_object_unref (task); -- GitLab From 0f40eb364b404ab8080ddc0503b31b080261a139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Wed, 26 Feb 2025 09:35:20 +0100 Subject: [PATCH 3/6] MessageList: Remove message_list in RegenData It is available in the GTask. --- src/mail/message-list.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index d772c3d27f..956a60b6a3 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -148,7 +148,6 @@ struct _RegenData { volatile gint ref_count; EActivity *activity; - MessageList *message_list; ETableSortInfo *sort_info; ETableHeader *full_header; @@ -483,7 +482,6 @@ regen_data_new (MessageList *message_list, regen_data = g_slice_new0 (RegenData); regen_data->ref_count = 1; regen_data->activity = g_object_ref (activity); - regen_data->message_list = g_object_ref (message_list); regen_data->folder = message_list_ref_folder (message_list); regen_data->last_row = -1; @@ -530,7 +528,6 @@ regen_data_unref (RegenData *regen_data) if (g_atomic_int_dec_and_test (®en_data->ref_count)) { g_clear_object (®en_data->activity); - g_clear_object (®en_data->message_list); g_clear_object (®en_data->sort_info); g_clear_object (®en_data->full_header); @@ -6967,8 +6964,7 @@ message_list_regen_idle_cb (gpointer user_data) task = G_TASK (user_data); regen_data = g_task_get_task_data (task); - - message_list = regen_data->message_list; + message_list = g_task_get_source_object (task); g_mutex_lock (&message_list->priv->regen_lock); -- GitLab From bdaaa85feae9f8b15058e0f2451be5105cf92fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Wed, 26 Feb 2025 09:45:49 +0100 Subject: [PATCH 4/6] MessageList: deal with EActivity instead of RegenData when cancelling --- src/mail/message-list.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index 956a60b6a3..2f5fc5971e 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -7019,12 +7019,12 @@ message_list_regen_idle_cb (gpointer user_data) static void mail_regen_cancel (MessageList *message_list) { - RegenData *regen_data = NULL; + EActivity *activity = NULL; g_mutex_lock (&message_list->priv->regen_lock); if (message_list->priv->regen_data != NULL) - regen_data = regen_data_ref (message_list->priv->regen_data); + activity = g_object_ref (message_list->priv->regen_data->activity); if (message_list->priv->regen_idle_source) { g_source_destroy (message_list->priv->regen_idle_source); @@ -7034,9 +7034,9 @@ mail_regen_cancel (MessageList *message_list) g_mutex_unlock (&message_list->priv->regen_lock); /* Cancel outside the lock, since this will emit a signal. */ - if (regen_data != NULL) { - e_activity_cancel (regen_data->activity); - regen_data_unref (regen_data); + if (activity != NULL) { + e_activity_cancel (activity); + g_object_unref (activity); } } -- GitLab From b3e441ee71ce534c0254c5ebeaf3d3b7d33e0b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Wed, 26 Feb 2025 10:29:18 +0100 Subject: [PATCH 5/6] MessageList: Use GTask instead of RegenData to keep track of current task GTask is owning the regendata so it makes sense to track its lifetime here. --- src/mail/message-list.c | 101 +++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index 2f5fc5971e..4d19776f78 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -85,7 +85,7 @@ struct _MessageListPrivate { /* For message list regeneration. */ GMutex regen_lock; - RegenData *regen_data; + GTask *regen_task; GSource *regen_idle_source; gboolean thaw_needs_regen; @@ -508,17 +508,6 @@ regen_data_new (MessageList *message_list, return regen_data; } -static RegenData * -regen_data_ref (RegenData *regen_data) -{ - g_return_val_if_fail (regen_data != NULL, NULL); - g_return_val_if_fail (regen_data->ref_count > 0, NULL); - - g_atomic_int_inc (®en_data->ref_count); - - return regen_data; -} - static void regen_data_unref (RegenData *regen_data) { @@ -1152,7 +1141,6 @@ message_list_select_uid (MessageList *message_list, MessageListPrivate *priv; GHashTable *uid_nodemap; GNode *node = NULL; - RegenData *regen_data; g_return_if_fail (IS_MESSAGE_LIST (message_list)); @@ -1167,7 +1155,6 @@ message_list_select_uid (MessageList *message_list, node = g_hash_table_lookup (uid_nodemap, uid); g_mutex_lock (&message_list->priv->regen_lock); - regen_data = message_list->priv->regen_data; /* If we're busy or waiting to regenerate the message list, cache * the UID so we can try again when we're done. Otherwise if the @@ -1177,7 +1164,8 @@ message_list_select_uid (MessageList *message_list, * 1) Oldest unread message in the list, by date received. * 2) Newest read message in the list, by date received. */ - if (regen_data != NULL) { + if (message_list->priv->regen_task) { + RegenData *regen_data = g_task_get_task_data (message_list->priv->regen_task); g_mutex_lock (®en_data->select_lock); g_free (regen_data->select_uid); regen_data->select_uid = g_strdup (uid); @@ -1316,12 +1304,13 @@ message_list_select_prev_thread (MessageList *message_list) void message_list_select_all (MessageList *message_list) { - RegenData *regen_data; + RegenData *regen_data = NULL; g_return_if_fail (IS_MESSAGE_LIST (message_list)); g_mutex_lock (&message_list->priv->regen_lock); - regen_data = message_list->priv->regen_data; + if (message_list->priv->regen_task) + regen_data = g_task_get_task_data (message_list->priv->regen_task); if (regen_data != NULL && regen_data->group_by_threads) { regen_data->select_all = TRUE; @@ -3460,7 +3449,7 @@ message_list_dispose (GObject *object) g_mutex_lock (&message_list->priv->regen_lock); /* This can happen when the regen_idle_source is removed before it's invoked */ - g_clear_pointer (&message_list->priv->regen_data, regen_data_unref); + g_clear_object (&message_list->priv->regen_task); g_mutex_unlock (&message_list->priv->regen_lock); @@ -5125,7 +5114,7 @@ message_list_folder_changed (CamelFolder *folder, MessageList *message_list) { CamelFolderChangeInfo *altered_changes = NULL; - gboolean has_regen_data; + gboolean has_regen_task; gboolean need_list_regen = TRUE; g_return_if_fail (CAMEL_IS_FOLDER (folder)); @@ -5136,12 +5125,12 @@ message_list_folder_changed (CamelFolder *folder, return; g_mutex_lock (&message_list->priv->regen_lock); - has_regen_data = message_list->priv->regen_data != NULL; + has_regen_task = message_list->priv->regen_task != NULL; g_mutex_unlock (&message_list->priv->regen_lock); d ( - printf ("%s: has_regen_data:%s changes:%p added:%d removed:%d changed:%d recent:%d for '%s'\n", - G_STRFUNC, has_regen_data ? "yes": "no", changes, + printf ("%s: has_regen_task:%s changes:%p added:%d removed:%d changed:%d recent:%d for '%s'\n", + G_STRFUNC, has_regen_task ? "yes": "no", changes, changes ? changes->uid_added->len : -1, changes ? changes->uid_removed->len : -1, changes ? changes->uid_changed->len : -1, @@ -5149,7 +5138,7 @@ message_list_folder_changed (CamelFolder *folder, camel_folder_get_full_name (folder))); /* Skip the quick update when the message list is being regenerated */ - if (changes && !has_regen_data) { + if (changes && !has_regen_task) { ETreeModel *tree_model; gboolean hide_junk; gboolean hide_deleted; @@ -6133,19 +6122,19 @@ void message_list_set_search (MessageList *message_list, const gchar *search) { - gboolean has_regen_data; + gboolean has_regen_task; g_return_if_fail (IS_MESSAGE_LIST (message_list)); g_mutex_lock (&message_list->priv->regen_lock); - has_regen_data = message_list->priv->regen_data != NULL; + has_regen_task = message_list->priv->regen_task != NULL; g_mutex_unlock (&message_list->priv->regen_lock); - if (!has_regen_data && (search == NULL || search[0] == '\0')) + if (!has_regen_task && (search == NULL || search[0] == '\0')) if (message_list->search == NULL || message_list->search[0] == '\0') return; - if (!has_regen_data && search != NULL && message_list->search != NULL && + if (!has_regen_task && search != NULL && message_list->search != NULL && strcmp (search, message_list->search) == 0) { return; } @@ -6586,9 +6575,8 @@ message_list_regen_done_cb (GObject *source_object, /* Withdraw our RegenData from the private struct, if it hasn't * already been replaced. We have exclusive access to it now. */ g_mutex_lock (&message_list->priv->regen_lock); - if (message_list->priv->regen_data == regen_data) { - regen_data_unref (message_list->priv->regen_data); - message_list->priv->regen_data = NULL; + if (message_list->priv->regen_task == G_TASK (result)) { + g_clear_object (&message_list->priv->regen_task); e_tree_set_info_message (E_TREE (message_list), NULL); } g_mutex_unlock (&message_list->priv->regen_lock); @@ -7019,25 +7007,31 @@ message_list_regen_idle_cb (gpointer user_data) static void mail_regen_cancel (MessageList *message_list) { - EActivity *activity = NULL; + GCancellable *cancellable = NULL; + GTask *regen_task = NULL; + gboolean idle_deleted = FALSE; g_mutex_lock (&message_list->priv->regen_lock); - if (message_list->priv->regen_data != NULL) - activity = g_object_ref (message_list->priv->regen_data->activity); + if (g_set_object (®en_task, message_list->priv->regen_task)) + cancellable = g_task_get_cancellable (regen_task); if (message_list->priv->regen_idle_source) { g_source_destroy (message_list->priv->regen_idle_source); g_clear_pointer (&message_list->priv->regen_idle_source, g_source_unref); + idle_deleted = TRUE; } g_mutex_unlock (&message_list->priv->regen_lock); /* Cancel outside the lock, since this will emit a signal. */ - if (activity != NULL) { - e_activity_cancel (activity); - g_object_unref (activity); - } + if (cancellable != NULL) + g_cancellable_cancel (cancellable); + + if (idle_deleted && regen_task) + g_task_return_error_if_cancelled (regen_task); + + g_clear_object (®en_task); } static void @@ -7048,13 +7042,15 @@ mail_regen_list (MessageList *message_list, GTask *task; GCancellable *cancellable; RegenData *new_regen_data; - RegenData *old_regen_data; + GTask *old_regen_task = NULL; + RegenData *old_regen_data = NULL; gchar *tmp_search_copy = NULL; if (!search) { g_mutex_lock (&message_list->priv->regen_lock); - old_regen_data = message_list->priv->regen_data; + if (message_list->priv->regen_task) + old_regen_data = g_task_get_task_data (message_list->priv->regen_task); if (old_regen_data && old_regen_data->folder == message_list->priv->folder) { tmp_search_copy = g_strdup (old_regen_data->search); @@ -7064,6 +7060,7 @@ mail_regen_list (MessageList *message_list, search = tmp_search_copy; } + old_regen_data = NULL; g_mutex_unlock (&message_list->priv->regen_lock); } else if (search && !*search) { search = NULL; @@ -7083,7 +7080,9 @@ mail_regen_list (MessageList *message_list, g_mutex_lock (&message_list->priv->regen_lock); - old_regen_data = message_list->priv->regen_data; + old_regen_task = g_steal_pointer (&message_list->priv->regen_task); + if (old_regen_task) + old_regen_data = g_task_get_task_data (old_regen_task); /* If a regen is scheduled but not yet started, just * apply the argument values without cancelling it. */ @@ -7115,6 +7114,7 @@ mail_regen_list (MessageList *message_list, /* Avoid cancelling on the way out. */ old_regen_data = NULL; + message_list->priv->regen_task = g_steal_pointer (&old_regen_task); goto exit; } @@ -7141,31 +7141,28 @@ mail_regen_list (MessageList *message_list, task = g_task_new (message_list, cancellable, message_list_regen_done_cb, NULL); g_task_set_source_tag (task, mail_regen_list); - g_task_set_task_data (task, - regen_data_ref (new_regen_data), - (GDestroyNotify) regen_data_unref); + g_task_set_task_data (task, new_regen_data, (GDestroyNotify) regen_data_unref); - /* Set the RegenData immediately, but start the actual regen - * operation from an idle callback. That way the caller has - * the remainder of this main loop iteration to make further - * MessageList changes without triggering additional regens. */ - - message_list->priv->regen_data = g_steal_pointer (&new_regen_data); message_list->priv->regen_idle_source = g_idle_source_new (); g_task_attach_source (task, message_list->priv->regen_idle_source, message_list_regen_idle_cb); + /* Set the regen_task immediately, but start the actual regen + * operation from an idle callback. That way the caller has + * the remainder of this main loop iteration to make further + * MessageList changes without triggering additional regens. */ + message_list->priv->regen_task = g_steal_pointer (&task); + g_object_unref (cancellable); - g_object_unref (task); exit: g_mutex_unlock (&message_list->priv->regen_lock); /* Cancel outside the lock, since this will emit a signal. */ - if (old_regen_data != NULL) { + if (old_regen_task != NULL) { e_activity_cancel (old_regen_data->activity); - regen_data_unref (old_regen_data); + g_clear_object (&old_regen_task); } g_free (tmp_search_copy); -- GitLab From 4bb7f0dfb5d32226351d31c25f94b652c42f0332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Wed, 26 Feb 2025 10:37:41 +0100 Subject: [PATCH 6/6] MessageList: Remove reference count to RegenData Its lifetime is bound to the corresponding GTask now. --- src/mail/message-list.c | 55 ++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/src/mail/message-list.c b/src/mail/message-list.c index 4d19776f78..b5c39ec6f3 100644 --- a/src/mail/message-list.c +++ b/src/mail/message-list.c @@ -145,8 +145,6 @@ struct _ExtendedGNode { }; struct _RegenData { - volatile gint ref_count; - EActivity *activity; ETableSortInfo *sort_info; ETableHeader *full_header; @@ -480,7 +478,6 @@ regen_data_new (MessageList *message_list, e_activity_set_text (activity, _("Generating message list")); regen_data = g_slice_new0 (RegenData); - regen_data->ref_count = 1; regen_data->activity = g_object_ref (activity); regen_data->folder = message_list_ref_folder (message_list); regen_data->last_row = -1; @@ -509,46 +506,36 @@ regen_data_new (MessageList *message_list, } static void -regen_data_unref (RegenData *regen_data) +regen_data_free (RegenData *regen_data) { g_return_if_fail (regen_data != NULL); - g_return_if_fail (regen_data->ref_count > 0); - - if (g_atomic_int_dec_and_test (®en_data->ref_count)) { - - g_clear_object (®en_data->activity); - g_clear_object (®en_data->sort_info); - g_clear_object (®en_data->full_header); - g_free (regen_data->search); + g_clear_object (®en_data->activity); + g_clear_object (®en_data->sort_info); + g_clear_object (®en_data->full_header); - if (regen_data->thread_tree != NULL) - camel_folder_thread_messages_unref ( - regen_data->thread_tree); + g_clear_pointer (®en_data->search, g_free); + g_clear_pointer (®en_data->thread_tree, camel_folder_thread_messages_unref); - if (regen_data->summary != NULL) { - guint ii, length; + if (regen_data->summary != NULL) { + guint ii, length; - length = regen_data->summary->len; + length = regen_data->summary->len; - for (ii = 0; ii < length; ii++) - g_clear_object (®en_data->summary->pdata[ii]); - - g_ptr_array_free (regen_data->summary, TRUE); - } + for (ii = 0; ii < length; ii++) + g_clear_object (®en_data->summary->pdata[ii]); - if (regen_data->removed_uids) - g_hash_table_destroy (regen_data->removed_uids); - g_clear_object (®en_data->folder); - - if (regen_data->expand_state != NULL) - xmlFreeDoc (regen_data->expand_state); + g_clear_pointer (®en_data->summary, g_ptr_array_unref); + } - g_mutex_clear (®en_data->select_lock); - g_free (regen_data->select_uid); + g_clear_pointer (®en_data->removed_uids, g_hash_table_unref); + g_clear_object (®en_data->folder); + g_clear_pointer (®en_data->expand_state, xmlFreeDoc); + g_mutex_clear (®en_data->select_lock); + g_clear_pointer (®en_data->select_uid, g_free); + g_free (regen_data->select_uid); - g_slice_free (RegenData, regen_data); - } + g_slice_free (RegenData, regen_data); } static void @@ -7141,7 +7128,7 @@ mail_regen_list (MessageList *message_list, task = g_task_new (message_list, cancellable, message_list_regen_done_cb, NULL); g_task_set_source_tag (task, mail_regen_list); - g_task_set_task_data (task, new_regen_data, (GDestroyNotify) regen_data_unref); + g_task_set_task_data (task, new_regen_data, (GDestroyNotify) regen_data_free); message_list->priv->regen_idle_source = g_idle_source_new (); g_task_attach_source (task, -- GitLab