Re: Hello, I'm new...



Hi Hector,

I cleaned out my inbox and accidentally erased some balsa-list stuff, so
I can't easily respond point-by-point..

You mentioned that you're interested in helping w/ threads. I initially
sent my threads patch only to people who expressed an interest, but I'll
be happy to post it here.  It seems to work fairly well (for me), with one
exception -- I created a callback function in the main thread to update a
"progress" dialog window, and the window works, apparently randomly, about
10% of the time on my system.  An fprintf to stderr from the callback
function itself shows that it is being called by the thread, and that it
has the correct label string, so I don't know why it isn't working.  If
you're good w/ gtk and familiar with threads you could help to fix this.

If you plan to apply the patch, you'll have to work with the CVS code --
so you may want to set this up first.  (This may also circumvent that
compilation problem you're having.)

David

PS - I've attached a diff file, and a tarball w/ 2 new files,
libbalsa/threads.h and src/threads.h .  I'm not sure how to get CVS diff
to do something similar to diff's -P option. (To treat new files as
additions to empty files, allowing patch to create them.)

? thread.diff
? libbalsa/threads.h
? src/threads.h
Index: libbalsa/libbalsa.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/libbalsa.c,v
retrieving revision 1.11
diff -c -r1.11 libbalsa.c
*** libbalsa/libbalsa.c	1999/02/21 15:27:56	1.11
--- libbalsa/libbalsa.c	1999/10/03 18:54:47
***************
*** 61,66 ****
--- 61,76 ----
  void
  libmutt_set_gui_update_hook (int count, int total)
  {
+ 
+ /*  This code is no longer needed w/ multi-threaded mail. */  
+ 
+ #if 0
    while (gtk_events_pending ())
      gtk_main_iteration ();
+ 
+   pthread_mutex_lock( &checking_mail );
+   gui_update = FALSE;
+   pthread_mutex_unlock( &checking_mail );
+ #endif
+ 
  }
Index: libbalsa/mailbox.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/mailbox.c,v
retrieving revision 1.90
diff -c -r1.90 mailbox.c
*** libbalsa/mailbox.c	1999/09/26 21:14:37	1.90
--- libbalsa/mailbox.c	1999/10/03 18:54:50
***************
*** 28,66 ****
  #include <sys/stat.h>
  #include <string.h>
  #include <time.h>
  
  #include "mailbackend.h"
  
  #include "mailbox.h"
  #include "misc.h"
  
  #define BUFFER_SIZE 1024
  
- 
  #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)
--- 28,86 ----
  #include <sys/stat.h>
  #include <string.h>
  #include <time.h>
+ #include <pthread.h>
  
  #include "mailbackend.h"
  
  #include "mailbox.h"
  #include "misc.h"
+ #include "threads.h"
  
  #define BUFFER_SIZE 1024
  
  #define LOCK_MAILBOX(mailbox)\
  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 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)
***************
*** 195,200 ****
--- 215,237 ----
  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;
+   }
+   g_free( current_dialog_message );
+   current_dialog_message = g_strdup( "IMAP... \n" );
+   pthread_mutex_unlock( &mailbox_lock );
+   if( GTK_IS_WIDGET( progress_text ) )
+      gtk_signal_emit_by_name( GTK_OBJECT( progress_text), "draw" );
+ 
+ /*  put IMAP code here */
+ 
+   return;  
+ 
  }
  
  
***************
*** 205,210 ****
--- 242,260 ----
    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;
+   }
+   g_free( current_dialog_message );
+   current_dialog_message = g_strdup( "Checking POP3... \n" );
+   pthread_mutex_unlock( &mailbox_lock );
+   if( GTK_IS_WIDGET( progress_text ))
+      gtk_signal_emit_by_name( GTK_OBJECT( progress_text), "draw" );
+ 
    list = g_list_first (mailboxes);
  
    if (to->type != MAILBOX_MBOX)
***************
*** 244,250 ****
  	  g_free (PopPass);
  	  g_free (PopUser);
  
! 	  if( strcmp( MAILBOX_POP3 (mailbox)->last_popped_uid, uid ) != 0 )
  	  {
  	      g_free ( MAILBOX_POP3 (mailbox)->last_popped_uid );
  		  MAILBOX_POP3 (mailbox)->last_popped_uid = g_strdup ( uid );
--- 294,301 ----
  	  g_free (PopPass);
  	  g_free (PopUser);
  
! 	  if( MAILBOX_POP3 (mailbox)->last_popped_uid == NULL
! 	      ||  strcmp( MAILBOX_POP3 (mailbox)->last_popped_uid, uid ) != 0 )
  	  {
  	      g_free ( MAILBOX_POP3 (mailbox)->last_popped_uid );
  		  MAILBOX_POP3 (mailbox)->last_popped_uid = g_strdup ( uid );
***************
*** 254,262 ****
--- 305,325 ----
  	}
        list = list->next;
      }
+     return;
  }
  
  void
+ libmutt_update_progress(char *s )
+ {
+   pthread_mutex_lock( &mailbox_lock );
+   g_free( current_dialog_message );
+   current_dialog_message = g_strdup( s );
+   pthread_mutex_unlock( &mailbox_lock );
+   if( GTK_IS_WIDGET( progress_text ) )
+      gtk_signal_emit_by_name( GTK_OBJECT( progress_text), "draw" );
+ }
+ 
+ void
  add_mailboxes_for_checking (Mailbox * mailbox)
  {
    BUFFY **tmp;
***************
*** 555,560 ****
--- 618,636 ----
    gint i = 0;
    gint index_hint;
  
+ /*  Only run if lock has been set */
+   pthread_mutex_lock( &mailbox_lock);
+   if( !checking_mail )
+   {
+      pthread_mutex_unlock( &mailbox_lock);
+      return FALSE;
+   }
+   g_free( current_dialog_message );
+   current_dialog_message = g_strdup( "Checking Local... \n" );
+   pthread_mutex_unlock( &mailbox_lock );
+   if( GTK_IS_WIDGET( progress_text ))
+      gtk_signal_emit_by_name( GTK_OBJECT( progress_text ), "draw" );
+ 
    if (!mailbox)
      return FALSE;
  
***************
*** 570,576 ****
      }
    else if (i == M_NEW_MAIL || i == M_REOPENED)
      {
!       // g_print ("got new mail! yippie!\n");
        mailbox->new_messages = CLIENT_CONTEXT (mailbox)->msgcount - mailbox->messages;
  
        if (mailbox->new_messages > 0)
--- 646,652 ----
      }
    else if (i == M_NEW_MAIL || i == M_REOPENED)
      {
!       g_print ("got new mail! yippie!\n");
        mailbox->new_messages = CLIENT_CONTEXT (mailbox)->msgcount - mailbox->messages;
  
        if (mailbox->new_messages > 0)
***************
*** 742,755 ****
        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();
      }
  }
  
--- 818,824 ----
        mailbox->new_messages--;
       
        if (emit)
! 		  send_watcher_new_message (mailbox, message, mailbox->new_messages);
      }
  }
  
Index: libmutt/pop.c
===================================================================
RCS file: /cvs/gnome/balsa/libmutt/pop.c,v
retrieving revision 1.8
diff -c -r1.8 pop.c
*** libmutt/pop.c	1999/09/26 21:14:37	1.8
--- libmutt/pop.c	1999/10/03 18:54:56
***************
*** 83,90 ****
    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,91 ----
    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;
+   char *progress_message = NULL;
    CONTEXT ctx;
    MESSAGE *msg = NULL;
  
***************
*** 243,255 ****
  
     }
    } 
-     	 
-   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);
      write (s, buffer, strlen (buffer));
  
--- 244,259 ----
  
     }
    } 
  
+   total = msgs - first_msg + 1;
+     	 
    for (i = first_msg ; i <= msgs ; i++)
    {
+ 	if( s != NULL)
+ 	   g_free( progress_message );
+     progress_message = g_strdup_printf( "POP3:  Retrieving %d of %d.", (i - first_msg + 1), total );
+     libmutt_update_progress( progress_message );
+ 
      snprintf (buffer, sizeof(buffer), "retr %d\r\n", i);
      write (s, buffer, strlen (buffer));
  
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/balsa/src/Makefile.am,v
retrieving revision 1.53
diff -c -r1.53 Makefile.am
*** src/Makefile.am	1999/07/31 19:23:15	1.53
--- src/Makefile.am	1999/10/03 18:54:58
***************
*** 57,62 ****
--- 57,64 ----
  	$(top_builddir)/libmutt/libmutt.a \
  	$(top_builddir)/libbalsa/libbalsa.a \
  	-lPropList	\
+ 	-lpthread	\
+ 	-lgthread	\
  	@LIBESD_LIB@	\
  	$(GNOME_LIBDIR) \
  	$(top_builddir)/idl/libbalsasrv.a \
Index: src/main-window.c
===================================================================
RCS file: /cvs/gnome/balsa/src/main-window.c,v
retrieving revision 1.197
diff -c -r1.197 main-window.c
*** src/main-window.c	1999/08/01 23:04:10	1.197
--- src/main-window.c	1999/10/03 18:55:00
***************
*** 22,29 ****
  #include <gnome.h>
  #include <gdk/gdkx.h>
  #include <X11/Xutil.h>
  
- 
  #include "balsa-app.h"
  #include "balsa-icons.h"
  #include "balsa-index.h"
--- 22,29 ----
  #include <gnome.h>
  #include <gdk/gdkx.h>
  #include <X11/Xutil.h>
+ #include <pthread.h>
  
  #include "balsa-app.h"
  #include "balsa-icons.h"
  #include "balsa-index.h"
***************
*** 40,45 ****
--- 40,46 ----
  #include "sendmsg-window.h"
  #include "mailbox-conf.h"
  #include "mblist-window.h"
+ #include "threads.h"
  #define MAILBOX_DATA "mailbox_data"
  
  #define APPBAR_KEY "balsa_appbar"
***************
*** 56,65 ****
  
  /* dialogs */
  static void show_about_box (void);
! 
  
  /* callbacks */
  static void check_new_messages_cb (GtkWidget *, gpointer data);
  
  static void new_message_cb (GtkWidget * widget, gpointer data);
  static void replyto_message_cb (GtkWidget * widget, gpointer data);
--- 57,67 ----
  
  /* dialogs */
  static void show_about_box (void);
! void check_all_show_progress( void );
  
  /* callbacks */
  static void check_new_messages_cb (GtkWidget *, gpointer data);
+ gint progress_window_change_cb (GtkWidget * widget, gpointer data);
  
  static void new_message_cb (GtkWidget * widget, gpointer data);
  static void replyto_message_cb (GtkWidget * widget, gpointer data);
***************
*** 479,502 ****
  static void
  check_new_messages_cb (GtkWidget * widget, gpointer data)
  {
!   GtkWidget *dialog, *w;
  
!   dialog = gnome_dialog_new("Checking Mail...", GNOME_STOCK_BUTTON_OK, NULL);
!   gnome_dialog_set_close(GNOME_DIALOG(dialog), TRUE);
  
!   w = gtk_label_new("Checking Mail....");
!   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);
  
    if (balsa_app.current_index_child != NULL)
      mailbox_check_new_messages (BALSA_INDEX (balsa_app.current_index_child->index)->mailbox);
  
!   gtk_label_set_text(GTK_LABEL(w), N_("Checked."));
! //  gtk_widget_destroy(dialog);
  }
  
  static void
--- 481,569 ----
  static void
  check_new_messages_cb (GtkWidget * widget, gpointer data)
  {
! /*  Only Run once -- If already checking mail, return.  */
!    pthread_mutex_lock( &mailbox_lock );
!    if( checking_mail )
!    {
!      pthread_mutex_unlock( &mailbox_lock );
!      return;
!    }
!    checking_mail = 1;
! 
! /*  create progress dialog:
!  *  see function check_all_show_progress below  -- David
!  */
!   progress_window = gnome_dialog_new("Checking Mail...", GNOME_STOCK_BUTTON_OK, NULL);
!   gnome_dialog_set_close(GNOME_DIALOG( progress_window ), TRUE);
  
!   g_free( current_dialog_message );
!   current_dialog_message = g_strdup( "Checking Mail....");
!   progress_text = gtk_label_new( current_dialog_message );
!   pthread_mutex_unlock( &mailbox_lock );
! 
!   gtk_signal_connect( GTK_OBJECT(progress_text),
!   						"event",
!   						GTK_SIGNAL_FUNC( progress_window_change_cb),
!   						NULL );
!   						
!   gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(progress_window)->vbox),
!   					progress_text, 
!   					FALSE, 
!   					FALSE, 
!   					0);
! 
!   gtk_widget_show_all( progress_window );
! 
! /* initiate threads */
!   pthread_create( &get_mail_thread,
!   					NULL,
!   					(void *) &check_messages_thread,
!   					(void *) NULL );
  
! }
  
! void
! check_messages_thread( void )
! {
! /*  
!  *  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);
  
    if (balsa_app.current_index_child != NULL)
      mailbox_check_new_messages (BALSA_INDEX (balsa_app.current_index_child->index)->mailbox);
+ 
+   pthread_mutex_lock( &mailbox_lock );
+   checking_mail = 0;
+   pthread_mutex_unlock( &mailbox_lock );
+ 
+   pthread_exit( 0 );
+ 
+ }
+ 
+ gint
+ progress_window_change_cb( GtkWidget *widget, gpointer data )
+ {
+    static gchar *display;
+ 
+    if( display )
+      g_free( display );
  
!    pthread_mutex_lock( &mailbox_lock);
!    display = g_strdup( current_dialog_message );
!    pthread_mutex_unlock( &mailbox_lock );
!    
!    if( progress_window )
!    {
! 	   gtk_label_set_text(GTK_LABEL( progress_text ), display );
! 	   fprintf( stderr, "progress_window_change_cb: %s \n", display );
!    }
!    
! 	return FALSE;
  }
  
  static void
Index: src/main-window.h
===================================================================
RCS file: /cvs/gnome/balsa/src/main-window.h,v
retrieving revision 1.13
diff -c -r1.13 main-window.h
*** src/main-window.h	1999/02/21 15:28:24	1.13
--- src/main-window.h	1999/10/03 18:55:00
***************
*** 28,32 ****
--- 28,33 ----
  void main_window_set_mailbox (Mailbox * mailbox);
  void main_window_set_cursor (gint type);
  void mblist_close_mailbox (Mailbox * mailbox);
+ void check_messages_thread( void );
  
  #endif /* __main_window_h__ */
Index: src/main.c
===================================================================
RCS file: /cvs/gnome/balsa/src/main.c,v
retrieving revision 1.50
diff -c -r1.50 main.c
*** src/main.c	1999/07/31 19:23:15	1.50
--- src/main.c	1999/10/03 18:55:00
***************
*** 20,33 ****
  #include "config.h"
  
  #include <gnome.h>
  #include <libgnorba/gnorba.h>
  #include <orb/orbit.h>
  
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  
- 
  #include "balsa-app.h"
  #include "balsa-icons.h"
  #include "balsa-init.h"
--- 20,34 ----
  #include "config.h"
  
  #include <gnome.h>
+ #include <glib.h>
  #include <libgnorba/gnorba.h>
  #include <orb/orbit.h>
  
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
+ #include <pthread.h>
  
  #include "balsa-app.h"
  #include "balsa-icons.h"
  #include "balsa-init.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,178 ----
      }
  }
  
+ void
+ threads_init( gboolean init )
+ {
+   if( init )
+   {
+     g_thread_init( NULL );
+     pthread_mutex_init( &mailbox_lock, NULL );
+     checking_mail = 0;
+     current_dialog_message = g_strdup( "" );
+     progress_text = NULL;
+     progress_window = NULL;
+   }
+   else
+   {
+     pthread_mutex_destroy( &mailbox_lock );
+   }
+ }
+ 
  int
  main (int argc, char *argv[])
  {
***************
*** 176,184 ****
--- 197,212 ----
  
    gnome_triggers_do ("", "program", "balsa", "startup", NULL);
  
+   threads_init( TRUE );
+ 
    main_window_init ();
  
+   gdk_threads_enter();
    gtk_main ();
+   gdk_threads_leave();
+ 
+   threads_init( FALSE );
+   
    return 0;
  }
  

new_files.tgz



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