Changeset 3813

Show
Ignore:
Timestamp:
11/19/08 15:45:25
Author:
svillar
Message:

Added some extra locking to prevent two sending threads running at the same time

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • releases/modest/diablo-pe2/ChangeLog

    r3812 r3813  
    112008-11-19  Sergio Villar Senin  <svillar@igalia.com> 
    22 
     3        * libtinymail-camel/tny-camel-send-queue.c 
     4        * libtinymail-camel/tny-camel-send-queue-priv.c: 
     5        added some extra locking to prevent two send queue threads running 
     6        at the same time 
     7 
    38        * libtinymail-camel/tny-camel-mime-part.c 
    4         (tny_camel_mime_part_decode_to_stream_default):  
     9        (tny_camel_mime_part_decode_to_stream_default): 
    510        adds a reference to protect wrapper when decoding to a stream 
    611 
  • releases/modest/diablo-pe2/libtinymail-camel/tny-camel-send-queue-priv.h

    r3439 r3813  
    3737        gboolean observer_attached; 
    3838        gint pending_send_notifies; 
     39        GStaticMutex *running_lock;  
    3940}; 
    4041 
  • releases/modest/diablo-pe2/libtinymail-camel/tny-camel-send-queue.c

    r3667 r3813  
    6969        gint i, total; 
    7070        guint signal_id; 
     71        GCond *condition; 
     72        GMutex *mutex; 
     73        gboolean had_callback; 
    7174} ControlInfo; 
    7275 
     
    309312                tny_lockable_unlock (apriv->session->priv->ui_lock); 
    310313 
     314        if (info->mutex) { 
     315                g_mutex_lock (info->mutex); 
     316                g_cond_broadcast (info->condition); 
     317                info->had_callback = TRUE; 
     318                g_mutex_unlock (info->mutex); 
     319        } 
     320 
    311321        return FALSE; 
    312322} 
     
    568578} 
    569579 
     580static void 
     581wait_for_queue_start_notification (TnySendQueue *self) 
     582{ 
     583        ControlInfo *info = g_slice_new0 (ControlInfo); 
     584 
     585        info->mutex = g_mutex_new (); 
     586        info->condition = g_cond_new (); 
     587        info->had_callback = FALSE; 
     588 
     589        info->self = g_object_ref (self); 
     590        info->signal_id = TNY_SEND_QUEUE_START; 
     591 
     592        g_idle_add (emit_queue_control_signals_on_mainloop, info); 
     593 
     594        g_mutex_lock (info->mutex); 
     595        if (!info->had_callback) 
     596                g_cond_wait (info->condition, info->mutex); 
     597        g_mutex_unlock (info->mutex); 
     598 
     599        g_mutex_free (info->mutex); 
     600        g_cond_free (info->condition); 
     601 
     602        g_slice_free (GetHeadersSync, info); 
     603} 
     604 
     605 
    570606static gpointer 
    571607thread_main (gpointer data) 
     
    579615        GHashTable *failed_headers = NULL; 
    580616 
    581         priv->is_running = TRUE; 
     617        /* Wait here until the user receives the queue-start notification */ 
     618        wait_for_queue_start_notification (self); 
     619 
    582620        list = tny_simple_list_new (); 
    583621 
     
    622660                                get_headers_sync (info->outbox, headers, TRUE, &ferror); 
    623661                        else { 
    624                                 priv->is_running = FALSE; 
    625662                                g_static_rec_mutex_unlock (priv->todo_lock); 
    626663                                g_static_rec_mutex_unlock (priv->sending_lock); 
     
    630667                        if (ferror != NULL) 
    631668                        { 
    632                                 priv->is_running = FALSE; 
    633669                                emit_error (self, NULL, NULL, ferror, i, priv->total); 
    634670                                g_error_free (ferror); 
     
    677713                        if (length <= 0) 
    678714                        { 
    679                                 priv->is_running = FALSE; 
    680715                                g_object_unref (headers); 
    681716                                g_static_rec_mutex_unlock (priv->todo_lock); 
     
    766801                } else  
    767802                { 
    768                         priv->is_running = FALSE; 
    769803                        /* Not good, or we just went offline, let's just kill this thread */  
    770804                        length = 0; 
     
    784818errorhandler: 
    785819 
    786         priv->is_running = FALSE; 
    787  
    788820        if (failed_headers) 
    789821                g_hash_table_destroy (failed_headers); 
     
    815847        g_slice_free (MainThreadInfo, info); 
    816848 
     849        g_static_mutex_lock (priv->running_lock); 
     850        priv->is_running = FALSE; 
     851        g_static_mutex_unlock (priv->running_lock); 
     852 
    817853        /* Emit the queue-stop signal */ 
    818854        emit_queue_control_signals (self, TNY_SEND_QUEUE_STOP); 
     
    828864        TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self); 
    829865 
     866        g_static_mutex_lock (priv->running_lock); 
    830867        if (!priv->is_running && priv->trans_account && TNY_IS_TRANSPORT_ACCOUNT (priv->trans_account)) 
    831868        { 
     
    872909                        } 
    873910 
    874                         emit_queue_control_signals (self, TNY_SEND_QUEUE_START); 
    875  
     911                        priv->is_running = TRUE; 
    876912                        priv->thread = g_thread_create (thread_main, info, FALSE, NULL); 
    877913 
    878914                        if (priv->thread == NULL) { 
    879                                 emit_queue_control_signals (self, TNY_SEND_QUEUE_STOP); 
     915                                GError *error; 
     916 
     917                                priv->is_running = FALSE; 
     918 
     919                                g_set_error (err, TNY_SYSTEM_ERROR,  
     920                                             TNY_SYSTEM_ERROR_UNKNOWN, 
     921                                             "Couldn't start thread for send queue"); 
     922                                emit_error (self, NULL, NULL, error, 0, 0); 
     923 
    880924                                if (TNY_IS_CAMEL_FOLDER (info->outbox)) { 
    881925                                        TnyCamelFolderPriv *opriv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->outbox); 
     
    889933                } 
    890934        } 
     935        g_static_mutex_unlock (priv->running_lock); 
    891936 
    892937        return; 
     
    910955        g_static_rec_mutex_lock (priv->sending_lock); 
    911956 
     957        g_static_mutex_lock (priv->running_lock); 
    912958        priv->is_running = FALSE; 
     959        g_static_mutex_unlock (priv->running_lock); 
    913960 
    914961        outbox = tny_send_queue_get_outbox (self); 
     
    9921039                priv->total++; 
    9931040 
    994         if (!err & !priv->is_running
     1041        if (!err
    9951042                create_worker (info->self, &new_err); 
    9961043 
     
    12711318        priv->sending_lock = NULL; 
    12721319 
     1320        g_free (priv->running_lock); 
     1321        priv->running_lock = NULL; 
     1322 
    12731323        g_object_unref (priv->trans_account); 
    12741324 
     
    14421492        priv->sending_lock = g_new0 (GStaticRecMutex, 1); 
    14431493        g_static_rec_mutex_init (priv->sending_lock); 
     1494        priv->running_lock = g_new0 (GStaticMutex, 1); 
     1495        g_static_mutex_init (priv->running_lock); 
    14441496 
    14451497        priv->is_running = FALSE;