--- empathy-2.29.93/src/empathy-chat-window.c	2010-03-24 09:31:05.461560854 +0100
+++ patched/src/empathy-chat-window.c	2010-03-24 09:20:26.149060248 +0100
@@ -78,6 +78,7 @@
 	EmpathyNotifyManager *notify_mgr;
 	GtkWidget   *dialog;
 	GtkWidget   *notebook;
+	GMutex      *notification_mutex;
 	NotifyNotification *notification;
 	NotificationData *notification_data;
 
@@ -1210,9 +1211,16 @@
 	}
 
 	g_object_unref (notify);
-	priv->notification = NULL;
 	free_notification_data (cb_data);
-	priv->notification_data = NULL;
+
+	g_mutex_lock (priv->notification_mutex);
+
+	if (priv->notification == notify) {
+		priv->notification = NULL;
+		priv->notification_data = NULL;
+	}
+
+	g_mutex_unlock (priv->notification_mutex);
 }
 
 static void
@@ -1226,7 +1234,7 @@
 	const char *body;
 	GdkPixbuf *pixbuf;
 	EmpathyChatWindowPriv *priv = GET_PRIV (window);
-	gboolean res;
+	gboolean res, has_x_canonical_append;
 
 	if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
 		return;
@@ -1242,8 +1250,12 @@
 	header = empathy_contact_get_name (sender);
 	body = empathy_message_get_body (message);
 	escaped = g_markup_escape_text (body, -1);
+	has_x_canonical_append = empathy_notify_manager_has_capability (priv->notify_mgr,
+		EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND);
 
-	if (priv->notification != NULL) {
+	g_mutex_lock (priv->notification_mutex);
+
+	if (priv->notification != NULL && ! has_x_canonical_append) {
 		notify_notification_update (priv->notification,
 					    header, escaped, NULL);
 	} else {
@@ -1258,6 +1270,11 @@
 
 		g_signal_connect (priv->notification, "closed",
 				  G_CALLBACK (chat_window_notification_closed_cb), cb_data);
+
+		if (has_x_canonical_append) {
+			notify_notification_set_hint_string (priv->notification,
+				EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "");
+		}
 	}
 
 	pixbuf = empathy_notify_manager_get_pixbuf_for_notification (priv->notify_mgr,
@@ -1270,6 +1287,8 @@
 
 	notify_notification_show (priv->notification, NULL);
 
+	g_mutex_unlock (priv->notification_mutex);
+
 	g_free (escaped);
 }
 
@@ -1760,9 +1779,10 @@
 	g_object_unref (priv->chatroom_manager);
 	g_object_unref (priv->notify_mgr);
 
+	g_mutex_lock (priv->notification_mutex);
+
 	if (priv->notification != NULL) {
 		notify_notification_close (priv->notification, NULL);
-		g_object_unref (priv->notification);
 		priv->notification = NULL;
 		if (priv->notification_data != NULL)
 			{
@@ -1771,6 +1791,9 @@
 			}
 	}
 
+	g_mutex_unlock (priv->notification_mutex);
+	g_mutex_free (priv->notification_mutex);
+
 	if (priv->contact_targets) {
 		gtk_target_list_unref (priv->contact_targets);
 	}
@@ -1957,6 +1980,11 @@
 	chat_windows = g_list_prepend (chat_windows, window);
 
 	/* Set up private details */
+	if (!g_thread_supported ()) {
+		g_thread_init (NULL);
+	}
+	priv->notification_mutex = g_mutex_new ();
+	priv->notification = NULL;
 	priv->chats = NULL;
 	priv->chats_new_msg = NULL;
 	priv->chats_composing = NULL;
--- empathy-2.29.93/src/empathy-status-icon.c	2010-03-24 09:31:05.411566860 +0100
+++ patched/src/empathy-status-icon.c	2010-03-24 09:27:57.809060956 +0100
@@ -65,6 +65,7 @@
 	guint                blink_timeout;
 	EmpathyEventManager *event_manager;
 	EmpathyEvent        *event;
+	GMutex              *notification_mutex;
 	NotifyNotification  *notification;
 
 	GtkWindow           *window;
@@ -95,11 +96,17 @@
 #ifdef notify_notification_get_closed_reason
 	reason = notify_notification_get_closed_reason (notification);
 #endif
-	if (priv->notification) {
-		g_object_unref (priv->notification);
+
+	g_object_unref (notification);
+
+	g_mutex_lock (priv->notification_mutex);
+
+	if (priv->notification == notification) {
 		priv->notification = NULL;
 	}
 
+	g_mutex_unlock (priv->notification_mutex);
+
 	if (!priv->event) {
 		return;
 	}
@@ -122,11 +129,15 @@
 static void
 notification_close_helper (EmpathyStatusIconPriv *priv)
 {
+	g_mutex_lock (priv->notification_mutex);
+
 	if (priv->notification) {
 		notify_notification_close (priv->notification, NULL);
 		g_object_unref (priv->notification);
 		priv->notification = NULL;
 	}
+
+	g_mutex_unlock (priv->notification_mutex);
 }
 
 static void
@@ -145,6 +156,7 @@
 {
 	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 	GdkPixbuf *pixbuf = NULL;
+	gboolean has_x_canonical_append;
 
 	if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
 		/* always close the notification if this happens */
@@ -158,7 +170,12 @@
 		if (priv->event->message != NULL)
 			message_esc = g_markup_escape_text (priv->event->message, -1);
 
-		if (priv->notification) {
+		has_x_canonical_append = empathy_notify_manager_has_capability (priv->notify_mgr,
+					EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND);
+
+		g_mutex_lock (priv->notification_mutex);
+
+		if (priv->notification != NULL && ! has_x_canonical_append) {
 			notify_notification_update (priv->notification,
 						    priv->event->header, message_esc,
 						    NULL);
@@ -168,6 +185,11 @@
 			notify_notification_set_timeout (priv->notification,
 							 NOTIFY_EXPIRES_DEFAULT);
 
+			if (has_x_canonical_append) {
+				notify_notification_set_hint_string (priv->notification,
+					EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "");
+			}
+
 			if (empathy_notify_manager_has_capability (priv->notify_mgr,
 			           EMPATHY_NOTIFY_MANAGER_CAP_ACTIONS) &&
 			           priv->event->type != EMPATHY_EVENT_TYPE_PRESENCE) {
@@ -195,6 +217,8 @@
 
 		notify_notification_show (priv->notification, NULL);
 
+		g_mutex_unlock (priv->notification_mutex);
+
 		g_free (message_esc);
 	} else {
 		notification_close_helper (priv);
@@ -400,11 +424,15 @@
 	if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
 		/* dismiss the outstanding notification if present */
 
+		g_mutex_lock (priv->notification_mutex);
+
 		if (priv->notification) {
 			notify_notification_close (priv->notification, NULL);
 			g_object_unref (priv->notification);
 			priv->notification = NULL;
 		}
+
+		g_mutex_unlock (priv->notification_mutex);
 	}
 }
 
@@ -560,12 +588,17 @@
 		g_source_remove (priv->blink_timeout);
 	}
 
+	g_mutex_lock (priv->notification_mutex);
+
 	if (priv->notification) {
 		notify_notification_close (priv->notification, NULL);
 		g_object_unref (priv->notification);
 		priv->notification = NULL;
 	}
 
+	g_mutex_unlock (priv->notification_mutex);
+	g_mutex_free (priv->notification_mutex);
+
 	g_object_unref (priv->icon);
 	g_object_unref (priv->account_manager);
 	g_object_unref (priv->event_manager);
@@ -652,6 +685,11 @@
 			  G_CALLBACK (status_icon_popup_menu_cb),
 			  icon);
 
+	if (!g_thread_supported ()) {
+		g_thread_init (NULL);
+	}
+	priv->notification_mutex = g_mutex_new ();
+	priv->notification = NULL;
 	priv->notify_mgr = empathy_notify_manager_dup_singleton ();
 }
 
