[balsa/gtk3] Use idle callback to insert message in main thread



commit 7db6063a3c553d000d8e11750cfdac082828355c
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Thu Jun 7 21:40:00 2012 -0400

    Use idle callback to insert message in main thread
    
    	* libbalsa/mailbox.c (lbm_msgno_inserted),
    	(lbm_msgno_inserted_idle_cb), (libbalsa_mailbox_msgno_inserted):
    	block subthread and use an idle callback to insert message in
    	main thread.
    	* libbalsa/mailbox_local.c
    	(libbalsa_mailbox_local_load_messages): do not grab GDK lock.

 ChangeLog                |    9 ++++
 libbalsa/mailbox.c       |   92 +++++++++++++++++++++++++++++++++++++++++++---
 libbalsa/mailbox_local.c |    5 --
 3 files changed, 95 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a8b005d..b481e9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2012-06-07  Peter Bloomfield
 
+	* libbalsa/mailbox.c (lbm_msgno_inserted),
+	(lbm_msgno_inserted_idle_cb), (libbalsa_mailbox_msgno_inserted):
+	block subthread and use an idle callback to insert message in
+	main thread.
+	* libbalsa/mailbox_local.c
+	(libbalsa_mailbox_local_load_messages): do not grab GDK lock.
+
+2012-06-07  Peter Bloomfield
+
 	* libbalsa/libbalsa.c (libbalsa_threads_enter): warn when
 	locking a subthread, to help find bad code paths.
 
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index 98239ef..5572221 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -1338,18 +1338,21 @@ libbalsa_mailbox_msgno_changed(LibBalsaMailbox * mailbox, guint seqno)
         gdk_threads_leave();
 }
 
-void
-libbalsa_mailbox_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno,
-                                GNode * parent, GNode ** sibling)
+static void
+lbm_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno, GNode * parent,
+                   GNode ** sibling)
 {
     GtkTreeIter iter;
     GtkTreePath *path;
     GSList **unthreaded;
 
-    if (!libbalsa_threads_has_lock())
-        g_warning("Thread is not holding gdk lock");
-    if (!mailbox->msg_tree)
+    gdk_threads_enter();
+
+    if (!mailbox->msg_tree) {
+        gdk_threads_leave();
         return;
+    }
+
 #undef SANITY_CHECK
 #ifdef SANITY_CHECK
     g_return_if_fail(!g_node_find(mailbox->msg_tree,
@@ -1378,6 +1381,83 @@ libbalsa_mailbox_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno,
             g_slist_prepend(*unthreaded, GUINT_TO_POINTER(seqno));
 
     mailbox->msg_tree_changed = TRUE;
+
+    gdk_threads_leave();
+}
+
+#ifdef BALSA_USE_THREADS
+typedef struct {
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    GMutex mutex;
+    GCond cond;
+#else                           /* GLIB_CHECK_VERSION(2, 32, 0) */
+    GMutex *mutex;
+    GCond *cond;
+#endif                          /* GLIB_CHECK_VERSION(2, 32, 0) */
+    LibBalsaMailbox *mailbox;
+    guint seqno;
+    GNode *parent;
+    GNode **sibling;
+    gboolean wait;
+} LbmMsgnoInsertedInfo;
+
+static gboolean
+lbm_msgno_inserted_idle_cb(LbmMsgnoInsertedInfo * info)
+{
+    lbm_msgno_inserted(info->mailbox, info->seqno, info->parent,
+                       info->sibling);
+    info->wait = FALSE;
+
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    g_cond_signal(&info->cond);
+#else                           /* GLIB_CHECK_VERSION(2, 32, 0) */
+    g_cond_signal(info->cond);
+#endif                          /* GLIB_CHECK_VERSION(2, 32, 0) */
+
+    return FALSE;
+}
+#endif                          /* BALSA_USE_THREADS */
+
+void
+libbalsa_mailbox_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno,
+                                GNode * parent, GNode ** sibling)
+{
+#ifdef BALSA_USE_THREADS
+    if (libbalsa_am_i_subthread()) {
+        LbmMsgnoInsertedInfo info;
+
+        info.mailbox = g_object_ref(mailbox);
+        info.seqno = seqno;
+        info.parent = parent;
+        info.sibling = sibling;
+        info.wait = TRUE;
+#if GLIB_CHECK_VERSION(2, 32, 0)
+        g_mutex_init(&info.mutex);
+        g_cond_init(&info.cond);
+        g_mutex_lock(&info.mutex);
+        g_idle_add((GSourceFunc) lbm_msgno_inserted_idle_cb, &info);
+        while (info.wait)
+            g_cond_wait(&info.cond, &info.mutex);
+        g_mutex_unlock(&info.mutex);
+        g_mutex_clear(&info.mutex);
+        g_cond_clear(&info.cond);
+#else                           /* GLIB_CHECK_VERSION(2, 32, 0) */
+        info.mutex = g_mutex_new();
+        info.cond = g_cond_new();
+        g_mutex_lock(info.mutex);
+        g_idle_add((GSourceFunc) lbm_msgno_inserted_idle_cb, &info);
+        while (info.wait)
+            g_cond_wait(info.cond, info.mutex);
+        g_mutex_unlock(info.mutex);
+        g_mutex_free(info.mutex);
+        g_cond_free(info.cond);
+#endif                          /* GLIB_CHECK_VERSION(2, 32, 0) */
+        g_object_unref(mailbox);
+    } else
+        lbm_msgno_inserted(mailbox, seqno, parent, sibling);
+#else                           /* BALSA_USE_THREADS */
+    lbm_msgno_inserted(mailbox, seqno, parent, sibling);
+#endif                          /* BALSA_USE_THREADS */
 }
 
 void
diff --git a/libbalsa/mailbox_local.c b/libbalsa/mailbox_local.c
index 8c5c90a..6486612 100644
--- a/libbalsa/mailbox_local.c
+++ b/libbalsa/mailbox_local.c
@@ -1023,11 +1023,8 @@ libbalsa_mailbox_local_load_messages(LibBalsaMailbox *mailbox,
 
     g_return_if_fail(LIBBALSA_IS_MAILBOX_LOCAL(mailbox));
 
-    gdk_threads_enter();
-
     if (!mailbox->msg_tree) {
 	/* Mailbox is closed, or no view has been created. */
-        gdk_threads_leave();
 	return;
     }
 
@@ -1046,8 +1043,6 @@ libbalsa_mailbox_local_load_messages(LibBalsaMailbox *mailbox,
                                                  msg_info->message);
     }
 
-    gdk_threads_leave();
-
     if (new_messages) {
 	libbalsa_mailbox_run_filters_on_reception(mailbox);
 	libbalsa_mailbox_set_unread_messages_flag(mailbox,



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