[balsa] Use separate mutexes for mailbox lock and check



commit d6cdd2d78aacd87f776e768e45976cac336f22cd
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Sun Sep 26 12:05:31 2010 -0400

    Use separate mutexes for mailbox lock and check
    
    	* libbalsa/libbalsa.c (libbalsa_lock_mailbox),
    	(libbalsa_unlock_mailbox): make the mutex static.
    	* libbalsa/libbalsa_private.h: ditto.
    	* src/main-window.c: use checking_mail_lock.
    	* src/main.c (threads_init), (threads_destroy), (balsa_cleanup):
    	* src/threads.h: ditto.

 ChangeLog                   |   11 +++++++++++
 libbalsa/libbalsa.c         |   16 ++++++++--------
 libbalsa/libbalsa_private.h |    1 -
 src/main-window.c           |   20 +++++++++-----------
 src/main.c                  |   21 ++++++---------------
 src/threads.h               |    5 ++---
 6 files changed, 36 insertions(+), 38 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1e06aa8..7c3acef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-09-26  Peter Bloomfield
+
+	Use separate mutexes for mailbox locking and checking mail
+
+	* libbalsa/libbalsa.c (libbalsa_lock_mailbox),
+	(libbalsa_unlock_mailbox): make the mutex static.
+	* libbalsa/libbalsa_private.h: ditto.
+	* src/main-window.c: use checking_mail_lock.
+	* src/main.c (threads_init), (threads_destroy), (balsa_cleanup):
+	* src/threads.h: ditto.
+
 2010-09-01  Peter Bloomfield
 
 	* src/main-window.c: hold gdk lock while updating UI.
diff --git a/libbalsa/libbalsa.c b/libbalsa/libbalsa.c
index 1da42db..12ed8e1 100644
--- a/libbalsa/libbalsa.c
+++ b/libbalsa/libbalsa.c
@@ -670,8 +670,8 @@ libbalsa_am_i_subthread(void)
 
 #ifdef BALSA_USE_THREADS
 #include "libbalsa_private.h"	/* for prototypes */
-pthread_mutex_t mailbox_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t mailbox_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mailbox_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t  mailbox_cond  = PTHREAD_COND_INITIALIZER;
 
 /* Lock/unlock a mailbox; no argument checking--we'll assume the caller
  * took care of that. 
@@ -703,10 +703,10 @@ libbalsa_lock_mailbox(LibBalsaMailbox * mailbox)
         gdk_threads_leave();
     }
 
-    pthread_mutex_lock(&mailbox_lock);
+    pthread_mutex_lock(&mailbox_mutex);
 
     while (mailbox->lock && mailbox->thread_id != thread_id)
-        pthread_cond_wait(&mailbox_cond, &mailbox_lock);
+        pthread_cond_wait(&mailbox_cond, &mailbox_mutex);
 
     /* We'll assume that no-one would destroy a mailbox while we've been
      * trying to lock it. If they have, we have larger problems than
@@ -714,7 +714,7 @@ libbalsa_lock_mailbox(LibBalsaMailbox * mailbox)
     mailbox->lock++;
     mailbox->thread_id = thread_id;
 
-    pthread_mutex_unlock(&mailbox_lock);
+    pthread_mutex_unlock(&mailbox_mutex);
 
     while (--count >= 0) {
         gdk_threads_enter();
@@ -731,11 +731,11 @@ libbalsa_unlock_mailbox(LibBalsaMailbox * mailbox)
 
     self = pthread_self();
 
-    pthread_mutex_lock(&mailbox_lock);
+    pthread_mutex_lock(&mailbox_mutex);
 
     if (mailbox->lock == 0 || self != mailbox->thread_id) {
 	g_warning("Not holding mailbox lock!!!");
-        pthread_mutex_unlock(&mailbox_lock);
+        pthread_mutex_unlock(&mailbox_mutex);
 	return;
     }
 
@@ -744,7 +744,7 @@ libbalsa_unlock_mailbox(LibBalsaMailbox * mailbox)
         mailbox->thread_id = 0;
     }
 
-    pthread_mutex_unlock(&mailbox_lock);
+    pthread_mutex_unlock(&mailbox_mutex);
 }
 
 /* Recursive mutex for gdk_threads_{enter,leave}. */
diff --git a/libbalsa/libbalsa_private.h b/libbalsa/libbalsa_private.h
index 467e9b4..2058d90 100644
--- a/libbalsa/libbalsa_private.h
+++ b/libbalsa/libbalsa_private.h
@@ -52,7 +52,6 @@ struct LibBalsaMailboxIndexEntry_ {
 
 #ifdef BALSA_USE_THREADS
 #include <pthread.h>
-extern pthread_mutex_t mailbox_lock;
 void libbalsa_lock_mailbox(LibBalsaMailbox * mailbox);
 void libbalsa_unlock_mailbox(LibBalsaMailbox * mailbox);
 #else
diff --git a/src/main-window.c b/src/main-window.c
index 9d05d10..4d2606a 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -1861,7 +1861,12 @@ balsa_window_new()
 
 #ifdef BALSA_USE_THREADS
     /* set initial state of Get-New-Mail button */
-    bw_set_sensitive(window, "GetNewMail", !checking_mail);
+    if (pthread_mutex_trylock(&checking_mail_lock))
+        bw_set_sensitive(window, "GetNewMail", FALSE);
+    else {
+        bw_set_sensitive(window, "GetNewMail", TRUE);
+        pthread_mutex_unlock(&checking_mail_lock);
+    }
 #endif
 
     gtk_widget_show(GTK_WIDGET(window));
@@ -2866,23 +2871,18 @@ check_new_messages_real(BalsaWindow * window, int type)
 #ifdef BALSA_USE_THREADS
     struct check_messages_thread_info *info;
     /*  Only Run once -- If already checking mail, return.  */
-    pthread_mutex_lock(&mailbox_lock);
-    if (checking_mail) {
-        pthread_mutex_unlock(&mailbox_lock);
+    if (pthread_mutex_trylock(&checking_mail_lock)) {
         fprintf(stderr, "Already Checking Mail!\n");
 	if (progress_dialog)
 	    gtk_window_present(GTK_WINDOW(progress_dialog));
         return;
     }
-    checking_mail = 1;
     if (window)
         bw_set_sensitive(window, "GetNewMail", FALSE);
 
     quiet_check = (type == TYPE_CALLBACK) 
         ? 0 : balsa_app.quiet_background_check;
 
-    pthread_mutex_unlock(&mailbox_lock);
-
     if (type == TYPE_CALLBACK && 
         (balsa_app.pwindow_option == WHILERETR ||
          (balsa_app.pwindow_option == UNTILCLOSED && progress_dialog)))
@@ -3055,7 +3055,6 @@ bw_check_messages_thread(struct check_messages_thread_info *info)
     /*  
      *  It is assumed that this will always be called as a pthread,
      *  and that the calling procedure will check for an existing lock
-     *  and set checking_mail to true before calling.
      */
     MailThreadMessage *threadmessage;
     GSList *list = info->list;
@@ -3072,15 +3071,14 @@ bw_check_messages_thread(struct check_messages_thread_info *info)
     MSGMAILTHREAD(threadmessage, LIBBALSA_NTFY_FINISHED, NULL, "Finished",
                   0, 0);
     
-    pthread_mutex_lock(&mailbox_lock);
-    checking_mail = 0;
+    pthread_mutex_unlock(&checking_mail_lock);
+
     if (info->window) {
         gdk_threads_enter();
         bw_set_sensitive(info->window, "GetNewMail", TRUE);
         g_object_unref(info->window);
         gdk_threads_leave();
     }
-    pthread_mutex_unlock(&mailbox_lock);
     
     g_free(info);
     pthread_exit(0);
diff --git a/src/main.c b/src/main.c
index 44cd72a..ed99ea9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -88,7 +88,6 @@
 pthread_t get_mail_thread;
 pthread_t send_mail;
 pthread_mutex_t send_messages_lock;
-int checking_mail;
 int mail_thread_pipes[2];
 int send_thread_pipes[2];
 GIOChannel *mail_thread_msg_send;
@@ -641,24 +640,17 @@ mailboxes_init(gboolean check_only)
 
 #ifdef BALSA_USE_THREADS
 
+pthread_mutex_t checking_mail_lock = PTHREAD_MUTEX_INITIALIZER;
+
 static void
 threads_init(void)
 {
-    int status;
-    pthread_mutexattr_t attr;
     g_thread_init(NULL);
     
-    if( (status=pthread_mutexattr_init(&attr)) )
-        g_warning("pthread_mutexattr_init failed with %d\n", status);
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&mailbox_lock, &attr);
-
     libbalsa_threads_init();
     gdk_threads_init();
 
-    pthread_mutexattr_destroy(&attr);
     pthread_mutex_init(&send_messages_lock, NULL);
-    checking_mail = 0;
     if (pipe(mail_thread_pipes) < 0) {
 	g_log("BALSA Init", G_LOG_LEVEL_DEBUG,
 	      "Error opening pipes.\n");
@@ -685,7 +677,7 @@ threads_init(void)
 static void
 threads_destroy(void)
 {
-    pthread_mutex_destroy(&mailbox_lock);
+    pthread_mutex_destroy(&checking_mail_lock);
     pthread_mutex_destroy(&send_messages_lock);
     libbalsa_threads_destroy();
 }
@@ -1194,8 +1186,7 @@ balsa_cleanup(void)
        There are actually many things to do, e.g. threads should not
        be started after this point.
     */
-    pthread_mutex_lock(&mailbox_lock);
-    if(checking_mail) {
+    if (pthread_mutex_trylock(&checking_mail_lock)) {
         /* We want to quit but there is a checking thread active.
            The alternatives are to:
            a. wait for the checking thread to finish - but it could be
@@ -1205,8 +1196,8 @@ balsa_cleanup(void)
         pthread_cancel(get_mail_thread);
         printf("Mail check thread cancelled. I know it is rough.\n");
         sleep(1);
-    }
-    pthread_mutex_unlock(&mailbox_lock);
+    } else
+        pthread_mutex_unlock(&checking_mail_lock);
 #endif
     balsa_app_destroy();
     g_hash_table_destroy(libbalsa_mailbox_view_table);
diff --git a/src/threads.h b/src/threads.h
index e13cbf3..1f60ac1 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -24,12 +24,11 @@
 
 #include <unistd.h>
 
-/* FIXME: mailbox_lock is really an internal libbalsa mutex. */
-extern pthread_mutex_t mailbox_lock;
+/*  allocated in main.c */
+extern pthread_mutex_t checking_mail_lock;
 
 /*  define thread globals */
 extern pthread_t get_mail_thread;
-extern int checking_mail;
 extern int mail_thread_pipes[2];
 extern GIOChannel *mail_thread_msg_send;
 extern GIOChannel *mail_thread_msg_receive;



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