[balsa/gtk3] Lock mailbox to avoid race



commit 1cdd9c6c4f386d82f27d2171bc7618f5311679fe
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon Mar 11 06:57:52 2013 -0400

    Lock mailbox to avoid race
    
        * libbalsa/mailbox.c (lbm_changed_idle_cb),
        (lbm_changed_schedule_idle), (libbalsa_mailbox_changed),
        (lbm_check_idle), (lbm_queue_check): lock the mailbox while
        storing the id of an idle call, to avoid a race with the main
        thread callback.
        * libbalsa/mailbox_local.c (lbm_local_queue_save_tree),
        (lbml_load_messages_idle_cb),
        (libbalsa_mailbox_local_load_messages),
        (libbalsa_mailbox_local_prepare_threading): ditto.

 ChangeLog                |   14 ++++++++++++++
 libbalsa/mailbox.c       |   16 +++++++++++++++-
 libbalsa/mailbox_local.c |   11 +++++++++++
 3 files changed, 40 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a190935..76c688d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2013-03-11  Peter Bloomfield
+
+       Lock mailbox to avoid race
+
+       * libbalsa/mailbox.c (lbm_changed_idle_cb),
+       (lbm_changed_schedule_idle), (libbalsa_mailbox_changed),
+       (lbm_check_idle), (lbm_queue_check): lock the mailbox while
+       storing the id of an idle call, to avoid a race with the main
+       thread callback.
+       * libbalsa/mailbox_local.c (lbm_local_queue_save_tree),
+       (lbml_load_messages_idle_cb),
+       (libbalsa_mailbox_local_load_messages),
+       (libbalsa_mailbox_local_prepare_threading): ditto.
+
 2013-03-07  Peter Bloomfield
 
        Use --with-gnome more carefully
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index 980e3cb..eae27c8 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -735,27 +735,34 @@ libbalsa_mailbox_check(LibBalsaMailbox * mailbox)
 static gboolean
 lbm_changed_idle_cb(LibBalsaMailbox * mailbox)
 {
+    libbalsa_lock_mailbox(mailbox);
     g_signal_emit(mailbox, libbalsa_mailbox_signals[CHANGED], 0);
     mailbox->changed_idle_id = 0;
+    libbalsa_unlock_mailbox(mailbox);
     return FALSE;
 }
 
 static void
 lbm_changed_schedule_idle(LibBalsaMailbox * mailbox)
 {
+    libbalsa_lock_mailbox(mailbox);
     if (!mailbox->changed_idle_id)
         mailbox->changed_idle_id =
             g_idle_add((GSourceFunc) lbm_changed_idle_cb, mailbox);
+    libbalsa_unlock_mailbox(mailbox);
 }
 
 void
 libbalsa_mailbox_changed(LibBalsaMailbox * mailbox)
 {
+    libbalsa_lock_mailbox(mailbox);
     if (!g_signal_has_handler_pending
-        (mailbox, libbalsa_mailbox_signals[CHANGED], 0, TRUE))
+        (mailbox, libbalsa_mailbox_signals[CHANGED], 0, TRUE)) {
         /* No one cares, so don't set any message counts--that might
          * cause mailbox->view to be created. */
+        libbalsa_unlock_mailbox(mailbox);
         return;
+    }
 
     if (MAILBOX_OPEN(mailbox)) {
         /* Both counts are valid. */
@@ -772,6 +779,7 @@ libbalsa_mailbox_changed(LibBalsaMailbox * mailbox)
     }
 
     lbm_changed_schedule_idle(mailbox);
+    libbalsa_unlock_mailbox(mailbox);
 }
 
 /* libbalsa_mailbox_message_match:
@@ -4323,16 +4331,22 @@ lbm_check_idle(LibBalsaMailbox * mailbox)
     lbm_check_real(mailbox);
 #endif                          /*BALSA_USE_THREADS */
 
+    libbalsa_lock_mailbox(mailbox);
+    mailbox->queue_check_idle_id = 0;
+    libbalsa_unlock_mailbox(mailbox);
+
     return FALSE;
 }
 
 static void
 lbm_queue_check(LibBalsaMailbox * mailbox)
 {
+    libbalsa_lock_mailbox(mailbox);
     if (!mailbox->queue_check_idle_id)
         mailbox->queue_check_idle_id =
             g_idle_add((GSourceFunc) lbm_check_idle,
                        g_object_ref(mailbox));
+    libbalsa_unlock_mailbox(mailbox);
 }
 
 /* Search mailbox for a message matching the condition in search_iter,
diff --git a/libbalsa/mailbox_local.c b/libbalsa/mailbox_local.c
index b9c47cd..ae26488 100644
--- a/libbalsa/mailbox_local.c
+++ b/libbalsa/mailbox_local.c
@@ -718,9 +718,13 @@ lbm_local_save_tree_idle(LibBalsaMailboxLocal * local)
 static void
 lbm_local_queue_save_tree(LibBalsaMailboxLocal * local)
 {
+    LibBalsaMailbox *mailbox = (LibBalsaMailbox *) local;
+
+    libbalsa_lock_mailbox(mailbox);
     if (!local->save_tree_id)
         local->save_tree_id =
             g_idle_add((GSourceFunc) lbm_local_save_tree_idle, local);
+    libbalsa_unlock_mailbox(mailbox);
 }
 
 /* 
@@ -1035,11 +1039,13 @@ lbml_load_messages_idle_cb(LibBalsaMailbox * mailbox)
     LibBalsaMailboxLocalMessageInfo *(*get_info) (LibBalsaMailboxLocal *,
                                                   guint);
 
+    libbalsa_lock_mailbox(mailbox);
     gdk_threads_enter();
 
     if (!mailbox->msg_tree) {
        /* Mailbox is closed, or no view has been created. */
         gdk_threads_leave();
+        libbalsa_unlock_mailbox(mailbox);
        return FALSE;
     }
 
@@ -1069,6 +1075,7 @@ lbml_load_messages_idle_cb(LibBalsaMailbox * mailbox)
     }
 
     local->load_messages_id = 0;
+    libbalsa_unlock_mailbox(mailbox);
     return FALSE;
 }
 
@@ -1081,11 +1088,13 @@ libbalsa_mailbox_local_load_messages(LibBalsaMailbox *mailbox,
     g_return_if_fail(LIBBALSA_IS_MAILBOX_LOCAL(mailbox));
 
     local = (LibBalsaMailboxLocal *) mailbox;
+    libbalsa_lock_mailbox(mailbox);
     if (!local->load_messages_id) {
         local->msgno = msgno;
         local->load_messages_id =
             g_idle_add((GSourceFunc) lbml_load_messages_idle_cb, mailbox);
     }
+    libbalsa_unlock_mailbox(mailbox);
 }
 
 /*
@@ -1317,6 +1326,7 @@ libbalsa_mailbox_local_prepare_threading(LibBalsaMailbox * mailbox,
     LibBalsaProgress progress = LIBBALSA_PROGRESS_INIT;
     gboolean retval = TRUE;
 
+    libbalsa_lock_mailbox(mailbox);
     libbalsa_mailbox_local_set_threading_info(local);
 
     text = g_strdup_printf(_("Preparing %s"), mailbox->name);
@@ -1352,6 +1362,7 @@ libbalsa_mailbox_local_prepare_threading(LibBalsaMailbox * mailbox,
                 g_idle_add((GSourceFunc) lbm_local_thread_idle, local);
         }
     }
+    libbalsa_unlock_mailbox(mailbox);
 
     return retval;
 }


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