[evolution-data-server] Bug 602287 - Avoid racing with camel_operation_mute()



commit 27dec99b4b55e57811e9bd2eb26cbaccf01a6f11
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Jul 22 07:28:24 2010 -0400

    Bug 602287 - Avoid racing with camel_operation_mute()

 camel/camel-operation.c |   47 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 34 insertions(+), 13 deletions(-)
---
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
index 7257655..f8f68e4 100644
--- a/camel/camel-operation.c
+++ b/camel/camel-operation.c
@@ -444,6 +444,8 @@ camel_operation_start (CamelOperation *cc, const gchar *what, ...)
 	va_list ap;
 	gchar *msg;
 	struct _status_stack *s;
+	CamelOperationStatusFunc status_func;
+	gpointer status_data;
 
 	if (cc == NULL)
 		cc = co_getcc();
@@ -468,9 +470,13 @@ camel_operation_start (CamelOperation *cc, const gchar *what, ...)
 	cc->lastreport = s;
 	cc->status_stack = g_slist_prepend(cc->status_stack, s);
 
+	/* This avoids a race with camel_operation_mute() after we unlock. */
+	status_func = cc->status;
+	status_data = cc->status_data;
+
 	UNLOCK();
 
-	cc->status(cc, msg, CAMEL_OPERATION_START, cc->status_data);
+	status_func (cc, msg, CAMEL_OPERATION_START, status_data);
 
 	d(printf("start '%s'\n", msg, pc));
 }
@@ -495,11 +501,16 @@ camel_operation_start_transient (CamelOperation *cc, const gchar *what, ...)
 	if (cc == NULL)
 		cc = co_getcc();
 
-	if (cc == NULL || cc->status == NULL)
+	if (cc == NULL)
 		return;
 
 	LOCK();
 
+	if (cc->status == NULL) {
+		UNLOCK();
+		return;
+	}
+
 	va_start(ap, what);
 	msg = g_strdup_vprintf(what, ap);
 	va_end(ap);
@@ -512,9 +523,6 @@ camel_operation_start_transient (CamelOperation *cc, const gchar *what, ...)
 	d(printf("start '%s'\n", msg, pc));
 
 	UNLOCK();
-
-	/* we dont report it yet */
-	/*cc->status(cc, msg, CAMEL_OPERATION_START, cc->status_data);*/
 }
 
 static guint stamp(void)
@@ -544,6 +552,8 @@ camel_operation_progress (CamelOperation *cc, gint pc)
 	guint now;
 	struct _status_stack *s;
 	gchar *msg = NULL;
+	CamelOperationStatusFunc status_func;
+	gpointer status_data;
 
 	if (cc == NULL)
 		cc = co_getcc();
@@ -565,10 +575,12 @@ camel_operation_progress (CamelOperation *cc, gint pc)
 	   they started, then they update every second */
 	now = stamp();
 	if (cc->status_update == now) {
-		cc = NULL;
+		UNLOCK();
+		return;
 	} else if (s->flags & CAMEL_OPERATION_TRANSIENT) {
 		if (s->stamp + CAMEL_OPERATION_TRANSIENT_DELAY > now) {
-			cc = NULL;
+			UNLOCK();
+			return;
 		} else {
 			cc->status_update = now;
 			cc->lastreport = s;
@@ -580,12 +592,15 @@ camel_operation_progress (CamelOperation *cc, gint pc)
 		msg = g_strdup(s->msg);
 	}
 
+	/* This avoids a race with camel_operation_mute() after we unlock. */
+	status_func = cc->status;
+	status_data = cc->status_data;
+
 	UNLOCK();
 
-	if (cc) {
-		cc->status(cc, msg, pc, cc->status_data);
-		g_free(msg);
-	}
+	status_func (cc, msg, pc, status_data);
+
+	g_free(msg);
 }
 
 /**
@@ -602,6 +617,8 @@ camel_operation_end (CamelOperation *cc)
 	guint now;
 	gchar *msg = NULL;
 	gint pc = 0;
+	CamelOperationStatusFunc status_func;
+	gpointer status_data;
 
 	if (cc == NULL)
 		cc = co_getcc();
@@ -652,10 +669,14 @@ camel_operation_end (CamelOperation *cc)
 	g_free(s);
 	cc->status_stack = g_slist_delete_link(cc->status_stack, cc->status_stack);
 
+	/* This avoids a race with camel_operation_mute() after we unlock. */
+	status_func = cc->status;
+	status_data = cc->status_data;
+
 	UNLOCK();
 
 	if (msg) {
-		cc->status(cc, msg, pc, cc->status_data);
-		g_free(msg);
+		status_func (cc, msg, pc, status_data);
+		g_free (msg);
 	}
 }



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