Multi-threaded mail, finally



OK,  first, the dislaimer!  :)

I've had only a couple hours of sleep, it's 3:30 in the morning, and I'm
hardly at my most articulate.  I have a working version of the thread code
that I want to share before I take a long Thanksgiving weekend.  It is
crude, messy, and needs some fundamental work in areas, but I'd like to
see what people think.  This is a diff against tonight's CVS code, AND a
tarball of two header files I've added.  I can't seem to get CVS's diff to
produce output that includes new files.

Here are some issues that need to be addressed:

First, someone could potentially cause serious problems by changing the
folder structure while mail is being downloaded.  (I don't think the basic
locking mechanism prevents this.)  So, I wonder if the best approach
wouldn't be to disable/grey-out the the preferences menu item while mail
is being downloaded, etc..

I don't know automake well enough to know where to put the linking
information for pthread.  I threw it in Makefile.am.  Someone could help
me out by letting me know where it 'should' go.

I've added pipes and callbacks to allow the mail thread to communicate
with the main thread, but haven't implemented all of the messages. The
callback function is named mail_progress_notify_cb because I had
originally planned to use it to update a progress dialog -- it should
still do this, but that's no longer a 'primary' function.  I'll rename it
before committing it to CVS.  Incidentally, The defined messages for
'source' and 'msginfo' will allow the thread to have a dialog in the main
window display like the following:

   email.mydomain.com
 Retrieving message 1 of 10

etc.

The current code uses config_mailbox_update to update certain information
about Unique IDs during the POP3 retrieval, and, of course, this a source
of potential conflict -- I'll move it to the callback soon.

On to other ugliness:

load_messages in mailbox.c, when called with emit, indirectly invokes GTK,
and therefore it causes problems in the thread.  There must be
some elegant way to dis-entangle that, but it was easier for me to make
load_messages public, and have the main thread call it.  I'll straighten
this out in the final version.

Finally (yes, finally), something seems to be locking a mailbox and, in
some rare situations, forgetting to unlock it.  This means that the
patched version of balsa does, occassionally, block while waiting for this
irresponsible function to release its lock.  It shouldn't be too difficult
to find the offending function (if this is what's happening), but I don't
have time to do it before I leave.

Any and all suggestions are welcomed!  (And, of course, if we decide not
to use threads, that's OK too.)  Unfortunately for those who don't have
multi-thread capable machines, evolution now appears to depend on threads
so the future of mail in gnome seems to be heading in this direction.

David


PS Despite the disclaimer, the patch has worked pretty consistently for me
tonight.

thread_files.tgz

? balsa/libbalsa/threads.h
? balsa/src/threads.h
Index: balsa/libbalsa/libbalsa.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/libbalsa.c,v
retrieving revision 1.11
diff -c -r1.11 libbalsa.c
*** balsa/libbalsa/libbalsa.c	1999/02/21 15:27:56	1.11
--- balsa/libbalsa/libbalsa.c	1999/11/24 08:09:55
***************
*** 58,66 ****
  {
  }
  
- void
- libmutt_set_gui_update_hook (int count, int total)
- {
-   while (gtk_events_pending ())
-     gtk_main_iteration ();
- }
--- 58,60 ----
Index: balsa/libbalsa/libbalsa.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/libbalsa.h,v
retrieving revision 1.2
diff -c -r1.2 libbalsa.h
*** balsa/libbalsa/libbalsa.h	1999/11/18 22:32:25	1.2
--- balsa/libbalsa/libbalsa.h	1999/11/24 08:09:55
***************
*** 31,34 ****
--- 31,36 ----
  #include "address.h"
  #include "body.h"
  
+ void load_messages (Mailbox * mailbox, gint emit);
+ 
  #endif /* __LIBBALSA_H__ */
Index: balsa/libbalsa/libbalsa_private.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/libbalsa_private.h,v
retrieving revision 1.1
diff -c -r1.1 libbalsa_private.h
*** balsa/libbalsa/libbalsa_private.h	1999/10/18 02:10:57	1.1
--- balsa/libbalsa/libbalsa_private.h	1999/11/24 08:09:55
***************
*** 2,30 ****
  
  #define LOCK_MAILBOX(mailbox)\
  do {\
!   if (mailbox->lock)\
      {\
!       g_print (_("*** ERROR: Mailbox Lock Exists: %s ***\n"), __PRETTY_FUNCTION__);\
!       return;\
      }\
    else\
!     mailbox->lock = TRUE;\
! } while (0)
! 
! 
  #define LOCK_MAILBOX_RETURN_VAL(mailbox, val)\
  do {\
!   if (mailbox->lock)\
      {\
!       g_print (_("*** ERROR: Mailbox Lock Exists: %s ***\n"), __PRETTY_FUNCTION__);\
!       return (val);\
      }\
    else\
!     mailbox->lock = TRUE;\
! } while (0)
! 
! #define UNLOCK_MAILBOX(mailbox)          mailbox->lock = FALSE;
  
  
  #define CLIENT_CONTEXT(mailbox)          (((MailboxPrivate *)((mailbox)->private))->context)
  #define CLIENT_CONTEXT_OPEN(mailbox)     (CLIENT_CONTEXT (mailbox) != NULL)
--- 2,50 ----
  
  #define LOCK_MAILBOX(mailbox)\
  do {\
!   pthread_mutex_lock( &mailbox_lock );\
!     if ( !mailbox->lock )\
      {\
! 	  fprintf( stderr, "Locking mailbox %s\n", mailbox->name );\
!       mailbox->lock = TRUE;\
!       pthread_mutex_unlock( &mailbox_lock );\
!       break;\
      }\
    else\
!     {\
!       fprintf( stderr, "... Mailbox lock collision ..." );\
!       pthread_mutex_unlock( &mailbox_lock );\
!       usleep( 250 );\
!     }\
!   } while ( 1 )
!   
  #define LOCK_MAILBOX_RETURN_VAL(mailbox, val)\
  do {\
!   pthread_mutex_lock( &mailbox_lock );\
!     if ( !mailbox->lock )\
      {\
! 	  fprintf( stderr, "Locking mailbox \n" );\
!       mailbox->lock = TRUE;\
!       pthread_mutex_unlock( &mailbox_lock );\
!       break;\
      }\
    else\
!     {\
!       fprintf( stderr, "Mailbox lock collision \n" );\
!       pthread_mutex_unlock( &mailbox_lock );\
!       usleep( 250 );\
!     }\
!   } while ( 1 )
  
+ #define UNLOCK_MAILBOX(mailbox)\
+ do {\
+   fprintf(stderr, "Unlocking mailbox \n" );\
+   pthread_mutex_lock( &mailbox_lock );\
+   mailbox->lock = FALSE;\
+   pthread_mutex_unlock( &mailbox_lock );\
+ }  while( 0 )
+   
+   
  
  #define CLIENT_CONTEXT(mailbox)          (((MailboxPrivate *)((mailbox)->private))->context)
  #define CLIENT_CONTEXT_OPEN(mailbox)     (CLIENT_CONTEXT (mailbox) != NULL)
Index: balsa/libbalsa/mailbox.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/mailbox.c,v
retrieving revision 1.97
diff -c -r1.97 mailbox.c
*** balsa/libbalsa/mailbox.c	1999/11/21 22:28:48	1.97
--- balsa/libbalsa/mailbox.c	1999/11/24 08:10:00
***************
*** 28,33 ****
--- 28,34 ----
  #include <sys/stat.h>
  #include <string.h>
  #include <time.h>
+ #include <pthread.h>
  
  #include "mailbackend.h"
  
***************
*** 35,40 ****
--- 36,42 ----
  #include "libbalsa_private.h"
  
  #include "misc.h"
+ #include "threads.h"
  
  #define BUFFER_SIZE 1024
  
***************
*** 65,71 ****
  /* 
   * prototypes
   */
! static void load_messages (Mailbox * mailbox, gint emit);
  static void free_messages (Mailbox * mailbox);
  
  
--- 67,73 ----
  /* 
   * prototypes
   */
! /* static void load_messages (Mailbox * mailbox, gint emit); */
  static void free_messages (Mailbox * mailbox);
  
  
***************
*** 142,147 ****
--- 144,163 ----
  void
  check_all_imap_hosts (Mailbox * to, GList *mailboxes)
  {
+ /*  Only check if lock has been set */
+   pthread_mutex_lock( &mailbox_lock);
+   if( !checking_mail )
+   {
+     pthread_mutex_unlock( &mailbox_lock);
+     return;
+   }
+   pthread_mutex_unlock( &mailbox_lock );
+ 
+ /*  put IMAP code here */
+ 
+ 
+   return;  
+ 
  }
  
  
***************
*** 152,157 ****
--- 168,183 ----
    Mailbox *mailbox;
    char uid[80];
  
+ /*  Only check if lock has been set */
+   pthread_mutex_lock( &mailbox_lock);
+   if( !checking_mail )
+   {
+     pthread_mutex_unlock( &mailbox_lock);
+     return;
+   }
+   pthread_mutex_unlock( &mailbox_lock );
+ 
+ 
    list = g_list_first (mailboxes);
  
   /* if (to->type != MAILBOX_MBOX)
***************
*** 197,207 ****
        {
          g_free ( MAILBOX_POP3 (mailbox)->last_popped_uid );
          MAILBOX_POP3 (mailbox)->last_popped_uid = g_strdup ( uid );
!         config_mailbox_update( mailbox, MAILBOX_POP3 (mailbox)->mailbox.name );
        }
      }
      list = list->next;
    }
  }
  
  void
--- 223,236 ----
        {
          g_free ( MAILBOX_POP3 (mailbox)->last_popped_uid );
          MAILBOX_POP3 (mailbox)->last_popped_uid = g_strdup ( uid );
! 
!         /* todo - move to callback from pipe, in main thread */
!         config_mailbox_update( mailbox, MAILBOX_POP3 (mailbox)->mailbox.name ); 
        }
      }
      list = list->next;
    }
+   return;
  }
  
  void
***************
*** 591,596 ****
--- 620,635 ----
  {
    gint i = 0;
    gint index_hint;
+   char msgbuf[160];
+ 
+ /*  Only run if lock has been set */
+   pthread_mutex_lock( &mailbox_lock);
+   if( !checking_mail )
+   {
+      pthread_mutex_unlock( &mailbox_lock);
+      return FALSE;
+   }
+   pthread_mutex_unlock( &mailbox_lock );
  
    if (!mailbox)
      return FALSE;
***************
*** 618,625 ****
--- 657,672 ----
  	  /* TODO:the preceeding two lines should be put in load_messages 
  	     but I don't want to rely on the 'emit' flag to know if there is REALLY 
  	     new mail in the mailbox. -bertrand */
+ 
+      sprintf( msgbuf, "%d:%s", MSGMAILTHREAD_LOAD, mailbox->name );
+      UNLOCK_MAILBOX (mailbox);
+        
+      write( mail_thread_pipes[1], msgbuf, strlen(msgbuf) );
+ 
+ /*
  	  load_messages (mailbox, 1);
  	  UNLOCK_MAILBOX (mailbox);
+ */
  	  return TRUE;
  	}
        else
***************
*** 735,741 ****
  /*
   * private
   */
! static void
  load_messages (Mailbox * mailbox, gint emit)
  {
    glong msgno;
--- 782,788 ----
  /*
   * private
   */
! void
  load_messages (Mailbox * mailbox, gint emit)
  {
    glong msgno;
***************
*** 779,792 ****
        mailbox->new_messages--;
       
        if (emit)
! 	{
! 	  send_watcher_new_message (mailbox, message, mailbox->new_messages);
! 	}
!       /* 
!        * give time to gtk so the GUI isn't blocked
!        * this is kinda a hack right now
!        */
!       update_gui_func();
      }
  }
  
--- 826,832 ----
        mailbox->new_messages--;
       
        if (emit)
!         send_watcher_new_message (mailbox, message, mailbox->new_messages);
      }
  }
  
Index: balsa/libbalsa/message.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/message.c,v
retrieving revision 1.3
diff -c -r1.3 message.c
*** balsa/libbalsa/message.c	1999/10/18 02:39:04	1.3
--- balsa/libbalsa/message.c	1999/11/24 08:10:01
***************
*** 26,34 ****
--- 26,36 ----
  #include <sys/stat.h>
  #include <string.h>
  #include <time.h>
+ #include <pthread.h>
  
  #include "mailbackend.h"
  
+ #include "threads.h"
  #include "libbalsa.h"
  #include "libbalsa_private.h"
  
Index: balsa/libmutt/mbox.c
===================================================================
RCS file: /cvs/gnome/balsa/libmutt/mbox.c,v
retrieving revision 1.6
diff -c -r1.6 mbox.c
*** balsa/libmutt/mbox.c	1998/09/06 17:54:19	1.6
--- balsa/libmutt/mbox.c	1999/11/24 08:10:05
***************
*** 262,269 ****
  #ifdef LIBMUTT
        if (count > i)
        {
-         libmutt_set_gui_update_hook(count,
- 			ftell (ctx->fp) / (ctx->size / 100 + 1));
          i+=50;
        }
  #endif
--- 262,267 ----
Index: balsa/libmutt/mh.c
===================================================================
RCS file: /cvs/gnome/balsa/libmutt/mh.c,v
retrieving revision 1.5
diff -c -r1.5 mh.c
*** balsa/libmutt/mh.c	1998/08/31 01:18:41	1.5
--- balsa/libmutt/mh.c	1999/11/24 08:10:07
***************
*** 390,396 ****
  #ifdef LIBMUTT
      if (count > i)
      {
-       libmutt_set_gui_update_hook(count, 0);
        i+=50;
      }
  #endif
--- 390,395 ----
Index: balsa/libmutt/pop.c
===================================================================
RCS file: /cvs/gnome/balsa/libmutt/pop.c,v
retrieving revision 1.8
diff -c -r1.8 pop.c
*** balsa/libmutt/pop.c	1999/09/26 21:14:37	1.8
--- balsa/libmutt/pop.c	1999/11/24 08:10:08
***************
*** 83,89 ****
    char buffer[2048];
    char msgbuf[SHORT_STRING];
    char uid[80], last_uid[80];
!   int s, i, msgs, bytes, tmp, err = 0;
    int first_msg;
    CONTEXT ctx;
    MESSAGE *msg = NULL;
--- 83,89 ----
    char buffer[2048];
    char msgbuf[SHORT_STRING];
    char uid[80], last_uid[80];
!   int s, i, msgs, bytes, tmp, total, err = 0;
    int first_msg;
    CONTEXT ctx;
    MESSAGE *msg = NULL;
***************
*** 244,253 ****
     }
    } 
      	 
-   snprintf (msgbuf, sizeof (msgbuf),
- 	    "Reading %d new message%s (%d bytes)...", msgs - first_msg, msgs > 1 ? "s" : "", bytes);
-   mutt_message (msgbuf);
  
    for (i = first_msg ; i <= msgs ; i++)
    {
      snprintf (buffer, sizeof(buffer), "retr %d\r\n", i);
--- 244,252 ----
     }
    } 
      	 
  
+   total = msgs - first_msg + 1; /* will be used for display later */
+   
    for (i = first_msg ; i <= msgs ; i++)
    {
      snprintf (buffer, sizeof(buffer), "retr %d\r\n", i);
Index: balsa/src/Makefile.am
===================================================================
RCS file: /cvs/gnome/balsa/src/Makefile.am,v
retrieving revision 1.56
diff -c -r1.56 Makefile.am
*** balsa/src/Makefile.am	1999/11/23 21:03:23	1.56
--- balsa/src/Makefile.am	1999/11/24 08:10:08
***************
*** 60,65 ****
--- 60,67 ----
  	$(top_builddir)/libmutt/libmutt.a \
  	$(top_builddir)/libbalsa/libbalsa.a \
  	-lPropList	\
+ 	-lpthread  \
+ 	-lgthread  \
  	@LIBESD_LIB@	\
  	$(GNOME_LIBDIR) \
  	$(top_builddir)/idl/libbalsasrv.a \
Index: balsa/src/main-window.c
===================================================================
RCS file: /cvs/gnome/balsa/src/main-window.c,v
retrieving revision 1.208
diff -c -r1.208 main-window.c
*** balsa/src/main-window.c	1999/11/23 21:09:12	1.208
--- balsa/src/main-window.c	1999/11/24 08:10:11
***************
*** 22,29 ****
--- 22,31 ----
  #include <gnome.h>
  #include <gdk/gdkx.h>
  #include <X11/Xutil.h>
+ #include <pthread.h>
  
  #include "libbalsa.h"
+ #include "libbalsa_private.h"
  
  #include "balsa-app.h"
  #include "balsa-icons.h"
***************
*** 34,46 ****
  #include "balsa-index-page.h"
  #include "misc.h"
  #include "main.h"
- #include "main-window.h"
  #include "message-window.h"
  #include "pref-manager.h"
  #include "sendmsg-window.h"
  #include "mailbox-conf.h"
  #include "mblist-window.h"
  #include "print.h"
  #include "address-book.h"
  
  #define MAILBOX_DATA "mailbox_data"
--- 36,49 ----
  #include "balsa-index-page.h"
  #include "misc.h"
  #include "main.h"
  #include "message-window.h"
  #include "pref-manager.h"
  #include "sendmsg-window.h"
  #include "mailbox-conf.h"
  #include "mblist-window.h"
+ #include "main-window.h"
  #include "print.h"
+ #include "threads.h"
  #include "address-book.h"
  
  #define MAILBOX_DATA "mailbox_data"
***************
*** 54,59 ****
--- 57,63 ----
    LAST_SIGNAL
  };
  
+ extern void load_messages (Mailbox * mailbox, gint emit);
  
  
  static void balsa_window_class_init(BalsaWindowClass *klass);
***************
*** 62,67 ****
--- 66,72 ----
  static void balsa_window_real_open_mailbox(BalsaWindow *window, Mailbox *mailbox);
  static void balsa_window_real_close_mailbox(BalsaWindow *window, Mailbox *mailbox);
  static void balsa_window_destroy(GtkObject * object);
+ void check_messages_thread( Mailbox *mbox );
  
  static GtkWidget *balsa_window_create_preview_pane(BalsaWindow *window);
  GtkWidget *balsa_window_find_current_index(BalsaWindow *window);
***************
*** 678,685 ****
  static void
  check_new_messages_cb (GtkWidget * widget, gpointer data)
  {
    GtkWidget *dialog, *w;
-   GtkWidget *index;
  
    dialog = gnome_dialog_new("Checking Mail...", GNOME_STOCK_BUTTON_OK, NULL);
    gnome_dialog_set_close(GNOME_DIALOG(dialog), TRUE);
--- 683,690 ----
  static void
  check_new_messages_cb (GtkWidget * widget, gpointer data)
  {
+ /* ---  I'll revisit this when I add pipes and callbacks to the threads --  
    GtkWidget *dialog, *w;
  
    dialog = gnome_dialog_new("Checking Mail...", GNOME_STOCK_BUTTON_OK, NULL);
    gnome_dialog_set_close(GNOME_DIALOG(dialog), TRUE);
***************
*** 688,702 ****
    gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), w, FALSE, FALSE, 0);
  
    gtk_widget_show_all(dialog);
!   check_all_pop3_hosts (balsa_app.inbox, balsa_app.inbox_input);
!   check_all_imap_hosts (balsa_app.inbox, balsa_app.inbox_input);
  
    index = balsa_window_find_current_index(BALSA_WINDOW(data));
    if (index)
!     mailbox_check_new_messages(BALSA_INDEX(index)->mailbox);
  
!   gtk_label_set_text(GTK_LABEL(w), N_("Checked."));
!   //  gtk_widget_destroy(dialog);
  }
  
  
--- 693,788 ----
    gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), w, FALSE, FALSE, 0);
  
    gtk_widget_show_all(dialog);
! */
!   GtkWidget *index;
!   Mailbox *mbox;
! 
! /*  Only Run once -- If already checking mail, return.  */
!   pthread_mutex_lock( &mailbox_lock );
!   if( checking_mail )
!   {
!     pthread_mutex_unlock( &mailbox_lock );
!     fprintf( stderr, "Already Checking Mail!  \n");
!     return;
!   }
!   checking_mail = 1;
!   pthread_mutex_unlock( &mailbox_lock );
  
    index = balsa_window_find_current_index(BALSA_WINDOW(data));
    if (index)
!     mbox = BALSA_INDEX(index)->mailbox;
!   else
!     mbox = NULL;
! 
! /* initiate threads */
!   pthread_create( &get_mail_thread,
!   					NULL,
!   					(void *) &check_messages_thread,
!   					mbox );
! 
! }
! 
! void
! check_messages_thread( Mailbox *mbox )
! {
! /*  
!  *  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.
!  */
! 
!   check_all_pop3_hosts (balsa_app.inbox, balsa_app.inbox_input); 
!   check_all_imap_hosts (balsa_app.inbox, balsa_app.inbox_input);
! 
!   mailbox_check_new_messages( mbox );
! 
!   pthread_mutex_lock( &mailbox_lock );
!   checking_mail = 0;
!   pthread_mutex_unlock( &mailbox_lock );
! 
!   pthread_exit( 0 );
! 
! }
! 
! gboolean
! mail_progress_notify_cb( )
! {
!     Mailbox *mbox;
! 
! 	char msgbuffer[2049];
! 	char msgstring[2049];
! 	uint count;
! 	int message = 0;
! 
! 	g_io_channel_read( mail_thread_msg_receive, msgbuffer, 2048, &count );
! 	msgbuffer[count] = 0;  /* terminate message string to avoid unexpected behavior */
!     msgstring[0] = 0;
! 	
! 	sscanf( msgbuffer, "%d:%s", &message, msgstring );
! 
!     switch( message )
!     {
!         case MSGMAILTHREAD_SOURCE:
!         		fprintf( stderr, " Source String: %s\n", msgstring );
!         		break;
!         case MSGMAILTHREAD_MSGINFO:
!         		fprintf( stderr, " Message Info: %s\n", msgstring );
!         		break;
!         case MSGMAILTHREAD_UPDATECONFIG:
!         		fprintf( stderr, " Update Config: %s\n", msgstring );
!         		break;
!         case MSGMAILTHREAD_LOAD:
!         		fprintf( stderr, " Load Mail: %s \n", msgstring );
!                 LOCK_MAILBOX (balsa_app.inbox);
!         		load_messages (balsa_app.inbox, 1);
!         		UNLOCK_MAILBOX (balsa_app.inbox);
!         		break;
!         default:
!         		fprintf ( stderr, " Unknown: %u bytes read: %s \n", count, msgbuffer );
!      }
! 	
  
! 	return TRUE;
  }
  
  
Index: balsa/src/main-window.h
===================================================================
RCS file: /cvs/gnome/balsa/src/main-window.h,v
retrieving revision 1.16
diff -c -r1.16 main-window.h
*** balsa/src/main-window.h	1999/10/18 02:10:57	1.16
--- balsa/src/main-window.h	1999/11/24 08:10:11
***************
*** 61,66 ****
--- 61,67 ----
  void balsa_window_refresh(BalsaWindow *window);
  void balsa_window_open_mailbox();
  void balsa_window_close_mailbox();
+ gboolean mail_progress_notify_cb( );
  
  /*
  void close_main_window (void);
Index: balsa/src/main.c
===================================================================
RCS file: /cvs/gnome/balsa/src/main.c,v
retrieving revision 1.53
diff -c -r1.53 main.c
*** balsa/src/main.c	1999/10/18 02:10:57	1.53
--- balsa/src/main.c	1999/11/24 08:10:12
***************
*** 26,31 ****
--- 26,32 ----
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
+ #include <pthread.h>
  
  
  #include "balsa-app.h"
***************
*** 37,42 ****
--- 38,44 ----
  #include "save-restore.h"
  
  #include "main.h"
+ #include "threads.h"
  
  #include "balsa-impl.c"
  
***************
*** 44,49 ****
--- 46,52 ----
  static void balsa_init (int argc, char **argv);
  static void config_init (void);
  static void mailboxes_init (void);
+ static void threads_init( gboolean init );
  
  void Exception (CORBA_Environment *);
  
***************
*** 152,157 ****
--- 155,188 ----
      }
  }
  
+ void
+ threads_init( gboolean init )
+ {
+   if( init )
+   {
+     g_thread_init( NULL );
+     pthread_mutex_init( &mailbox_lock, NULL );
+     checking_mail = 0;
+ 	if( pipe( mail_thread_pipes) < 0 )
+ 	{
+ 	   g_log ("BALSA Init", G_LOG_LEVEL_DEBUG, "Error opening pipes.\n" );
+ 	}
+ 	mail_thread_msg_send = g_io_channel_unix_new ( mail_thread_pipes[1] );
+ 	mail_thread_msg_receive = g_io_channel_unix_new ( mail_thread_pipes[0] );
+ 	g_io_add_watch ( mail_thread_msg_receive, G_IO_IN,
+ 					mail_progress_notify_cb,
+ 					NULL );
+ 					
+   }
+   else
+   {
+     pthread_mutex_destroy( &mailbox_lock );
+   }
+ }
+ 
+ 
+ 
+ 
  int
  main (int argc, char *argv[])
  {
***************
*** 172,177 ****
--- 203,212 ----
    config_mailboxes_init ();
    mailboxes_init ();
  
+   /* initiate thread mutexs, variables */
+   threads_init( TRUE );
+   
+ 
    /* create all the pretty icons that balsa uses that
     * arn't part of gnome-libs */
    balsa_icons_init ();
***************
*** 182,187 ****
--- 217,225 ----
    gtk_widget_show(window);
  
    gtk_main ();
+ 
+   threads_init( FALSE );
+ 
    return 0;
  }
  


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