Index: calendar/ChangeLog
===================================================================
--- calendar/ChangeLog	(revision 8373)
+++ calendar/ChangeLog	(working copy)
@@ -1,3 +1,12 @@
+2008-01-16  Chenthill Palanisamy  <pchenthill@novell.com>
+
+	Fixes #503574
+	* backends/groupwise/e-cal-backend-groupwise.c: (delta_thread),
+	(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): Run get_deltas in a single thread.
+
 2008-01-07  P Chenthill <pchenthill@novell.com>
 
 	Reverting the fix for bug #503574.
Index: calendar/backends/groupwise/e-cal-backend-groupwise.c
===================================================================
--- calendar/backends/groupwise/e-cal-backend-groupwise.c	(revision 8369)
+++ calendar/backends/groupwise/e-cal-backend-groupwise.c	(working copy)
@@ -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,9 @@
 	/* fields for storing info while offline */
 	char *user_email;
 	char *local_attachments_store;
+
+	GThread *dthread;
+	SyncDelta *dlock;
 };
 
 static void e_cal_backend_groupwise_dispose (GObject *object);
@@ -637,25 +645,75 @@
 	return TRUE;
 }
 
-static gboolean
-get_deltas_timeout (gpointer cbgw)
+static gpointer
+delta_thread (gpointer data)
 {
-	GThread *thread;
+	ECalBackendGroupwise *cbgw = data;
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
+	GTimeVal timeout;
+
+	timeout.tv_sec = 0;
+	timeout.tv_usec = 0;
+
+	while (TRUE)	{
+		if (!get_deltas (cbgw) || priv->dlock->exit) {
+			priv->dthread = NULL;
+			return NULL;
+		}
+
+		g_mutex_lock (priv->dlock->mutex);
+		
+		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);
+		
+		g_mutex_unlock (priv->dlock->mutex);
+
+		if (priv->dlock->exit) {
+			priv->dthread = NULL;	
+			return NULL;
+		}
+	}
+}
+
+static void
+fetch_deltas (ECalBackendGroupwise *cbgw)
+{
+	ECalBackendGroupwisePrivate *priv = cbgw->priv;
 	GError *error = NULL;
 
-	if (!cbgw)
-		return FALSE;
-
-	thread = g_thread_create ((GThreadFunc) get_deltas, cbgw, FALSE, &error);
-	if (!thread) {
+	/* If the thread is already running just return back */	
+	if (priv->dthread) 
+		return;
+	
+	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);
 	}
+}
 
-	return TRUE;
+/* 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;
+
+	if (priv->mode == CAL_MODE_LOCAL)
+		return;
+
+	g_mutex_lock (priv->dlock->mutex);
+	g_cond_signal (priv->dlock->cond);
+	g_mutex_unlock (priv->dlock->mutex);
 }
 
-
 static char*
 form_uri (ESource *source)
 {
@@ -746,23 +804,17 @@
 			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;
+			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;
-		}
+		priv->mode = CAL_MODE_REMOTE;
+		fetch_deltas (cbgw);
+	
+		return GNOME_Evolution_Calendar_Success;
 	}
 }
 
@@ -900,20 +952,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;
+				fetch_deltas (cbgw);
+			}
 
-				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);
-			}
 			utc_str = (char *) e_gw_connection_get_server_time (priv->cnc);
 			e_cal_backend_cache_put_server_utc_time (priv->cache, utc_str);
 
@@ -1012,6 +1055,22 @@
 	priv = cbgw->priv;
 
 	/* Clean up */
+	if (priv->dlock) {
+		priv->dlock->exit = TRUE;
+		
+		g_mutex_lock (priv->dlock->mutex);
+		g_cond_signal (priv->dlock->cond);
+		g_mutex_unlock (priv->dlock->mutex);
+
+		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;
@@ -1052,11 +1111,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;
@@ -1162,11 +1216,14 @@
 	priv= cbgw->priv;
 	priv->read_only = TRUE;
 
-	if (priv->timeout_id) {
-		g_source_remove (priv->timeout_id);
-		priv->timeout_id =0;
-	}
+	if (priv->dlock) {
+		priv->dlock->exit = TRUE;
 
+		g_mutex_lock (priv->dlock->mutex);
+		g_cond_signal (priv->dlock->cond);
+		g_mutex_unlock (priv->dlock->mutex);
+	}	
+
 	if (priv->cnc) {
 		g_object_unref (priv->cnc);
 		priv->cnc = NULL;
@@ -2681,7 +2738,6 @@
 
 	priv = g_new0 (ECalBackendGroupwisePrivate, 1);
 
-	priv->timeout_id = 0;
 	priv->cnc = NULL;
 	priv->sendoptions_sync_timeout = 0;
 
