[evolution-data-server] Bug #687640 - Crash in caldav's initialize_backend()



commit 12a279cebfc5591d1d2ae0978b346dcdc3eccf97
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jan 15 14:46:37 2014 +0100

    Bug #687640 - Crash in caldav's initialize_backend()
    
    Two threads could call initialize_backend() simultaneously,
    overwriting data one to the other, which caused the crash.

 calendar/backends/caldav/e-cal-backend-caldav.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)
---
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 5f6e385..02961ed 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -5110,20 +5110,23 @@ caldav_source_changed_thread (gpointer data)
 
        old_slave_cmd = cbdav->priv->slave_cmd;
        old_slave_busy = cbdav->priv->slave_busy;
-       if (old_slave_busy) {
+       if (old_slave_busy)
                update_slave_cmd (cbdav->priv, SLAVE_SHOULD_SLEEP);
-               g_mutex_lock (&cbdav->priv->busy_lock);
-       }
 
+       g_mutex_lock (&cbdav->priv->busy_lock);
+
+       /* guard the call with busy_lock, thus the two threads (this 'source changed'
+          thread and the 'backend open' thread) will not clash on internal data
+          when they are called in once */
        initialize_backend (cbdav, NULL);
 
        /* always wakeup thread, even when it was sleeping */
        g_cond_signal (&cbdav->priv->cond);
 
-       if (old_slave_busy) {
+       if (old_slave_busy)
                update_slave_cmd (cbdav->priv, old_slave_cmd);
-               g_mutex_unlock (&cbdav->priv->busy_lock);
-       }
+
+       g_mutex_unlock (&cbdav->priv->busy_lock);
 
        cbdav->priv->updating_source = FALSE;
 
@@ -5141,7 +5144,9 @@ caldav_source_changed_cb (ESource *source,
        g_return_if_fail (source != NULL);
        g_return_if_fail (cbdav != NULL);
 
-       if (cbdav->priv->updating_source)
+       if (cbdav->priv->updating_source ||
+           !cbdav->priv->loaded ||
+           !e_cal_backend_is_opened (E_CAL_BACKEND (cbdav)))
                return;
 
        cbdav->priv->updating_source = TRUE;


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