evolution-data-server r8435 - in trunk/calendar: . backends/groupwise



Author: pchen
Date: Mon Jan 28 08:09:41 2008
New Revision: 8435
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8435&view=rev

Log:
2008-01-28  Chenthill Palanisamy  <pchenthill novell com>

        Fixes #503574
        * backends/groupwise/e-cal-backend-groupwise.c: (delta_thread),
        (fetch_deltas), (start_fetch_deltas),
        (e_cal_backend_groupwise_refresh_calendar), (cache_init),
        (connect_to_server), (e_cal_backend_groupwise_finalize),
        (in_offline), (e_cal_backend_groupwise_init): Fetch the deltas
        in a single thread.



Modified:
   trunk/calendar/ChangeLog
   trunk/calendar/backends/groupwise/e-cal-backend-groupwise.c

Modified: trunk/calendar/backends/groupwise/e-cal-backend-groupwise.c
==============================================================================
--- trunk/calendar/backends/groupwise/e-cal-backend-groupwise.c	(original)
+++ trunk/calendar/backends/groupwise/e-cal-backend-groupwise.c	Mon Jan 28 08:09:41 2008
@@ -59,6 +59,12 @@
 #define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
 #endif
 
+typedef struct {
+	GCond *cond;
+	GMutex *mutex;
+	gboolean exit;
+} SyncDelta;
+
 /* Private part of the CalBackendGroupwise structure */
 struct _ECalBackendGroupwisePrivate {
 	/* A mutex to control access to the private structure */
@@ -70,7 +76,6 @@
 	char *username;
 	char *password;
 	char *container_id;
-	int timeout_id;
 	CalMode mode;
 	gboolean mode_changed;
 	icaltimezone *default_zone;
@@ -86,6 +91,10 @@
 	/* fields for storing info while offline */
 	char *user_email;
 	char *local_attachments_store;
+
+	guint timeout_id;
+	GThread *dthread;
+	SyncDelta *dlock;
 };
 
 static void e_cal_backend_groupwise_dispose (GObject *object);
@@ -639,17 +648,58 @@
 	return TRUE;
 }
 
+static gpointer
+delta_thread (gpointer data)
+{
+	ECalBackendGroupwise *cbgw = data;
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
+	GTimeVal timeout;
+
+	timeout.tv_sec = 0;
+	timeout.tv_usec = 0;
+
+	while (TRUE)	{
+		gboolean succeeded = get_deltas (cbgw);
+
+		g_mutex_lock (priv->dlock->mutex);
+
+		if (!succeeded || priv->dlock->exit) 
+			break;
+
+		g_get_current_time (&timeout);
+		g_time_val_add (&timeout, CACHE_REFRESH_INTERVAL * 1000);
+		g_cond_timed_wait (priv->dlock->cond, priv->dlock->mutex, &timeout);
+		
+		if (priv->dlock->exit) 
+			break;	
+		
+		g_mutex_unlock (priv->dlock->mutex);
+	}
+
+	g_mutex_unlock (priv->dlock->mutex);
+	priv->dthread = NULL;	
+	return NULL;
+}
+
 static gboolean
-get_deltas_timeout (gpointer cbgw)
+fetch_deltas (ECalBackendGroupwise *cbgw)
 {
-	GThread *thread;
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
 	GError *error = NULL;
 
-	if (!cbgw)
+	/* If the thread is already running just return back */	
+	if (priv->dthread) 
 		return FALSE;
-
-	thread = g_thread_create ((GThreadFunc) get_deltas, cbgw, FALSE, &error);
-	if (!thread) {
+	
+	if (!priv->dlock) {
+		priv->dlock = g_new0 (SyncDelta, 1);
+		priv->dlock->mutex = g_mutex_new ();
+		priv->dlock->cond = g_cond_new ();
+	}
+	
+	priv->dlock->exit = FALSE;
+	priv->dthread = g_thread_create ((GThreadFunc) delta_thread, cbgw, TRUE, &error);
+	if (!priv->dthread) {
 		g_warning (G_STRLOC ": %s", error->message);
 		g_error_free (error);
 	}
@@ -658,6 +708,37 @@
 }
 
 
+static gboolean
+start_fetch_deltas (gpointer data)
+{
+	ECalBackendGroupwise *cbgw = data;
+
+	fetch_deltas (cbgw);
+
+	cbgw->priv->timeout_id = 0;
+	return FALSE;
+}
+
+
+/* TODO call it when a user presses SEND/RECEIVE or refresh*/
+static void
+e_cal_backend_groupwise_refresh_calendar (ECalBackendGroupwise *cbgw)
+{
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
+	gboolean delta_started = FALSE;
+
+	if (priv->mode == CAL_MODE_LOCAL)
+		return;
+
+	g_mutex_lock (priv->mutex);
+	delta_started = fetch_deltas (cbgw);
+	g_mutex_unlock (priv->mutex);
+
+	/* Emit the signal if the delta is already running */
+	if (!delta_started)
+		g_cond_signal (priv->dlock->cond);
+}
+
 static char*
 form_uri (ESource *source)
 {
@@ -692,7 +773,7 @@
 
 }
 
-static ECalBackendSyncStatus
+static gpointer 
 cache_init (ECalBackendGroupwise *cbgw)
 {
 	ECalBackendGroupwisePrivate *priv = cbgw->priv;
@@ -729,6 +810,8 @@
 		g_warning (G_STRLOC ": Could not get the categories from the server");
         }
 
+	priv->mode = CAL_MODE_REMOTE;
+
 	/* We poke the cache for a default timezone. Its
 	 * absence indicates that the cache file has not been
 	 * populated before. */
@@ -739,7 +822,7 @@
 		if (cnc_status != E_GW_CONNECTION_STATUS_OK) {
 			g_warning (G_STRLOC ": Could not populate the cache");
 			/*FIXME  why dont we do a notify here */
-			return GNOME_Evolution_Calendar_PermissionDenied;
+			return NULL;
 		} else {
 			char *utc_str;
 
@@ -747,25 +830,17 @@
 			e_cal_backend_cache_set_marker (priv->cache);
 			e_cal_backend_cache_put_server_utc_time (priv->cache, utc_str);
 
-			/*  Set up deltas only if it is a Calendar backend */
-			priv->timeout_id = g_timeout_add (time_interval, (GSourceFunc) get_deltas_timeout, (gpointer) cbgw);
-			priv->mode = CAL_MODE_REMOTE;
+			priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, start_fetch_deltas, cbgw);
 
-			return GNOME_Evolution_Calendar_Success;
-		}
-
-	} else {
-		/* get the deltas from the cache */
-		if (get_deltas (cbgw)) {
-			priv->timeout_id = g_timeout_add (time_interval, (GSourceFunc) get_deltas_timeout, (gpointer) cbgw);
-			priv->mode = CAL_MODE_REMOTE;
-			return GNOME_Evolution_Calendar_Success;
-		} else {
-			g_warning (G_STRLOC ": Could not populate the cache");
-			/*FIXME  why dont we do a notify here */
-			return GNOME_Evolution_Calendar_PermissionDenied;
+			return NULL;
 		}
 	}
+
+	g_mutex_lock (priv->mutex);
+	fetch_deltas (cbgw);
+	g_mutex_unlock (priv->mutex);
+
+	return NULL;
 }
 
 static ECalBackendSyncStatus
@@ -902,20 +977,11 @@
 		if (priv->cache && priv->container_id) {
 			char *utc_str;
 			priv->mode = CAL_MODE_REMOTE;
-			if (priv->mode_changed && !priv->timeout_id ) {
-				GThread *thread1;
+			if (priv->mode_changed && !priv->dthread) {
 				priv->mode_changed = FALSE;
-
-				thread1 = g_thread_create ((GThreadFunc) get_deltas, cbgw, FALSE, &error);
-				if (!thread1) {
-					g_warning (G_STRLOC ": %s", error->message);
-					g_error_free (error);
-
-					e_cal_backend_notify_error (E_CAL_BACKEND (cbgw), _("Could not create thread for getting deltas"));
-					return GNOME_Evolution_Calendar_OtherError;
-				}
-				priv->timeout_id = g_timeout_add (CACHE_REFRESH_INTERVAL, (GSourceFunc) get_deltas_timeout, (gpointer)cbgw);
+				fetch_deltas (cbgw);
 			}
+
 			utc_str = (char *) e_gw_connection_get_server_time (priv->cnc);
 			e_cal_backend_cache_put_server_utc_time (priv->cache, utc_str);
 
@@ -1014,6 +1080,28 @@
 	priv = cbgw->priv;
 
 	/* Clean up */
+
+	if (priv->timeout_id) {
+		g_source_remove (priv->timeout_id);
+		priv->timeout_id = 0;
+	}
+
+	if (priv->dlock) {
+		g_mutex_lock (priv->dlock->mutex);
+		priv->dlock->exit = TRUE;
+		g_mutex_unlock (priv->dlock->mutex);
+		
+		g_cond_signal (priv->dlock->cond);
+
+		if (priv->dthread)
+			g_thread_join (priv->dthread);
+		
+		g_mutex_free (priv->dlock->mutex);
+		g_cond_free (priv->dlock->cond);
+		g_free (priv->dlock);
+		priv->dthread = NULL;
+	}
+
 	if (priv->mutex) {
 		g_mutex_free (priv->mutex);
 		priv->mutex = NULL;
@@ -1054,11 +1142,6 @@
 		priv->local_attachments_store = NULL;
 	}
 
-	if (priv->timeout_id) {
-		g_source_remove (priv->timeout_id);
-		priv->timeout_id = 0;
-	}
-
 	if (priv->sendoptions_sync_timeout) {
 		g_source_remove (priv->sendoptions_sync_timeout);
 		priv->sendoptions_sync_timeout = 0;
@@ -1164,9 +1247,17 @@
 	priv= cbgw->priv;
 	priv->read_only = TRUE;
 
+	if (priv->dlock) {
+		g_mutex_lock (priv->dlock->mutex);
+		priv->dlock->exit = TRUE;
+		g_mutex_unlock (priv->dlock->mutex);
+
+		g_cond_signal (priv->dlock->cond);
+	}	
+
 	if (priv->timeout_id) {
 		g_source_remove (priv->timeout_id);
-		priv->timeout_id =0;
+		priv->timeout_id = 0;
 	}
 
 	if (priv->cnc) {
@@ -2685,7 +2776,6 @@
 
 	priv = g_new0 (ECalBackendGroupwisePrivate, 1);
 
-	priv->timeout_id = 0;
 	priv->cnc = NULL;
 	priv->sendoptions_sync_timeout = 0;
 



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