diff options
Diffstat (limited to 'mail/mail-threads.c')
-rw-r--r-- | mail/mail-threads.c | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/mail/mail-threads.c b/mail/mail-threads.c index ebd2570570..d0a20ee2be 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -32,6 +32,13 @@ /* FIXME: support other thread types!!!! */ #define USE_PTHREADS +/* FIXME TODO: Do we need operations that don't get a progress window because + * they're quick, but we still want camel to be locked? We need some kind + * of flag to mail_operation_try, but then we also need some kind of monitor + * to open the window if it takes more than a second or something. That would + * probably entail another thread.... + */ + /** * A function and its userdata **/ @@ -39,6 +46,9 @@ typedef struct closure_s { void (*func)( gpointer ); gpointer data; + + gchar *prettyname; + /* gboolean gets_window; */ } closure_t; /** @@ -83,7 +93,8 @@ static GtkWidget *queue_window_progress = NULL; /** * @op_queue: The list of operations the are scheduled - * to proceed after the currently executing one. + * to proceed after the currently executing one. When + * only one operation is going, this is NULL. **/ static GSList *op_queue = NULL; @@ -93,6 +104,9 @@ static GSList *op_queue = NULL; * with the main thread for GTK+ calls * * @chan_reader: the GIOChannel that reads our pipe + * + * @READER: the fd in our pipe that.... reads! + * @WRITER: the fd in our pipe that.... writes! */ #define READER compipe[0] @@ -120,11 +134,17 @@ static void remove_next_pending( void ); /** * @dispatch_thread: the pthread_t (when using pthreads, of - * course) representing our dispatcher routine. + * course) representing our dispatcher routine. Never used + * except to make pthread_create happy **/ + static pthread_t dispatch_thread; -/* FIXME: do we need to set any attributes for our thread? */ +/* FIXME: do we need to set any attributes for our thread? + * If so, we need to create a pthread_attr structure and + * fill it in somewhere. But the defaults should be good + * enough. + */ #else /* defined USE_PTHREADS */ choke on this: no thread type defined @@ -136,9 +156,16 @@ choke on this: no thread type defined * @callback: the function to call in another thread to start the operation * @user_data: extra data passed to the callback * - * Waits for the currently executing operation to finished, then - * executes the callback function in another thread. Returns TRUE - * on success, FALSE on some sort of queueing error. + * Runs a mail operation asynchronously. If no other operation is running, + * we start another thread and call the callback in that thread. The function + * can then use the mail_op_ functions to perform limited UI returns, while + * the main UI is completely unlocked. + * + * If an async operation is going on when this function is called again, + * it waits for the currently executing operation to finish, then + * executes the callback function in another thread. + * + * Returns TRUE on success, FALSE on some sort of queueing error. **/ gboolean @@ -150,11 +177,13 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi clur = g_new( closure_t, 1 ); clur->func = callback; clur->data = user_data; + clur->prettyname = g_strdup( description ); if( mail_operation_in_progress == FALSE ) { - /* We got the lock. Yippeee! This means that no operations - * are pending, either, so we'll create the queue window and - * show only the message and progress bar. + /* No operations are going on, none are pending. So + * we check to see if we're initialized (create the + * window and the pipes), and send off the operation + * on its merry way. */ mail_operation_in_progress = TRUE; @@ -177,10 +206,11 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi GtkWidget *label; /* Zut. We already have an operation running. Well, - * queue ourselves up. */ - - /* Yes, prepend is faster. But we pop operations - * off the beginning later and that's a lot easier. + * queue ourselves up. + * + * Yes, g_slist_prepend is faster down here.. But we pop + * operations off the beginning of the list later and + * that's a lot faster. */ op_queue = g_slist_append( op_queue, clur ); @@ -189,7 +219,7 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi label = gtk_label_new( description ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); gtk_box_pack_start( GTK_BOX( queue_window_pending ), label, - TRUE, TRUE, 2 ); + FALSE, TRUE, 2 ); /* If we want the next op to be on the bottom, uncomment this */ /* 1 = first on list always (0-based) */ @@ -337,22 +367,22 @@ create_queue_window( void ) vbox = gtk_vbox_new( FALSE, 4 ); - pending_vb = gtk_vbox_new( TRUE, 2 ); + pending_vb = gtk_vbox_new( FALSE, 2 ); queue_window_pending = pending_vb; pending_lb = gtk_label_new( _("Currently pending operations:") ); gtk_misc_set_alignment( GTK_MISC( pending_lb ), 0.0, 0.0 ); gtk_box_pack_start( GTK_BOX( pending_vb ), pending_lb, - TRUE, TRUE, 0 ); + FALSE, TRUE, 0 ); gtk_box_pack_start( GTK_BOX( vbox ), pending_vb, TRUE, TRUE, 4 ); /* FIXME: 'operation' is not the warmest cuddliest word. */ - progress_lb = gtk_label_new( _("Starting operation...") ); + progress_lb = gtk_label_new( "" ); queue_window_message = progress_lb; gtk_box_pack_start( GTK_BOX( vbox ), progress_lb, - TRUE, TRUE, 4 ); + FALSE, TRUE, 4 ); progress_bar = gtk_progress_bar_new(); queue_window_progress = progress_bar; @@ -362,7 +392,7 @@ create_queue_window( void ) gtk_progress_bar_set_bar_style( GTK_PROGRESS_BAR( progress_bar ), GTK_PROGRESS_CONTINUOUS ); gtk_box_pack_start( GTK_BOX( vbox ), progress_bar, - TRUE, TRUE, 4 ); + FALSE, TRUE, 4 ); gtk_container_add( GTK_CONTAINER( queue_window ), vbox ); } @@ -423,6 +453,7 @@ static void *dispatch_func( void *data ) closure_t *clur = (closure_t *) data; msg.type = STARTING; + msg.message = clur->prettyname; write( WRITER, &msg, sizeof( msg ) ); (clur->func)( clur->data ); @@ -430,6 +461,7 @@ static void *dispatch_func( void *data ) msg.type = FINISHED; write( WRITER, &msg, sizeof( msg ) ); + g_free( clur->prettyname ); g_free( data ); pthread_exit( 0 ); @@ -438,6 +470,8 @@ static void *dispatch_func( void *data ) /** * read_msg: + * @source: the channel that has data to read + * @condition: the reason we were called * @userdata: unused * * A message has been recieved on our pipe; perform the appropriate @@ -468,8 +502,7 @@ static gboolean read_msg( GIOChannel *source, GIOCondition condition, gpointer u switch( msg.type ) { case STARTING: - gtk_label_set_text( GTK_LABEL( queue_window_message ), - _("Starting operation...") ); + gtk_label_set_text( GTK_LABEL( queue_window_message ), msg.message ); gtk_progress_bar_update( GTK_PROGRESS_BAR( queue_window_progress ), 0.0 ); break; case PERCENTAGE: @@ -559,8 +592,4 @@ static void remove_next_pending( void ) /* Hide it? */ if( g_list_next( children ) == NULL ) gtk_widget_hide( queue_window_pending ); - - /* FIXME: The window gets really messed up here */ - gtk_container_resize_children( GTK_CONTAINER( queue_window_pending ) ); - gtk_container_resize_children( GTK_CONTAINER( queue_window ) ); } |