[evolution-mapi] Bug #668804 - Crash in ecbm_connect_user()



commit ef578a6e897d06eda741419682374b6e04b14e27
Author: Milan Crha <mcrha redhat com>
Date:   Wed Feb 1 14:36:25 2012 +0100

    Bug #668804 - Crash in ecbm_connect_user()

 src/account-setup-eplugin/e-mapi-account-setup.c   |   27 ------------
 src/account-setup-eplugin/e-mapi-account-setup.h   |    2 -
 .../e-mapi-edit-folder-permissions.c               |    2 +-
 src/addressbook/e-book-backend-mapi.c              |    4 +-
 src/calendar/e-cal-backend-mapi.c                  |   45 +++++++++++++++-----
 src/libexchangemapi/e-mapi-utils.c                 |   28 ++++++++++++
 src/libexchangemapi/e-mapi-utils.h                 |    3 +
 7 files changed, 69 insertions(+), 42 deletions(-)
---
diff --git a/src/account-setup-eplugin/e-mapi-account-setup.c b/src/account-setup-eplugin/e-mapi-account-setup.c
index bbfaead..ed414ff 100644
--- a/src/account-setup-eplugin/e-mapi-account-setup.c
+++ b/src/account-setup-eplugin/e-mapi-account-setup.c
@@ -1812,30 +1812,3 @@ e_mapi_account_open_connection_for (GtkWindow *parent,
 
 	return conn;
 }
-
-static gpointer
-unref_conn_in_thread (gpointer ptr)
-{
-	EMapiConnection *conn = ptr;
-
-	g_return_val_if_fail (conn != NULL, NULL);
-
-	g_object_unref (conn);
-
-	return NULL;
-}
-
-/* because this also disconnects from a server, which can take its time */
-void
-e_mapi_account_unref_conn_in_thread (EMapiConnection *conn)
-{
-	GError *error = NULL;
-
-	if (!conn)
-		return;
-
-	if (!g_thread_create (unref_conn_in_thread, conn, FALSE, &error)) {
-		g_warning ("%s: Failed to run thread: %s", G_STRFUNC, error ? error->message : "Unknown error");
-		g_object_unref (conn);
-	}
-}
diff --git a/src/account-setup-eplugin/e-mapi-account-setup.h b/src/account-setup-eplugin/e-mapi-account-setup.h
index 6d5d82e..77bed16 100644
--- a/src/account-setup-eplugin/e-mapi-account-setup.h
+++ b/src/account-setup-eplugin/e-mapi-account-setup.h
@@ -62,6 +62,4 @@ EMapiConnection	*	e_mapi_account_open_connection_for	(GtkWindow *parent,
 								 GCancellable *cancellable,
 								 GError **perror);
 
-void			e_mapi_account_unref_conn_in_thread	(EMapiConnection *conn);
-
 #endif /* E_MAPI_ACCOUNT_SETUP_H */
diff --git a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c b/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
index 4692d1c..8c8ef73 100644
--- a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
+++ b/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
@@ -154,7 +154,7 @@ edit_permissions_widgets_free (gpointer ptr)
 	g_free (widgets->login_url);
 	g_free (widgets->foreign_username);
 	if (widgets->conn)
-		e_mapi_account_unref_conn_in_thread (widgets->conn);
+		e_mapi_utils_unref_in_thread (G_OBJECT (widgets->conn));
 	g_free (widgets);
 }
 
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index ee7b98e..9a84877 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -1061,8 +1061,10 @@ ebbm_operation_cb (OperationBase *op, gboolean cancelled, EBookBackend *backend)
 		g_object_unref (op->cancellable);
 	if (op->book)
 		g_object_unref (op->book);
-	g_object_unref (ebma);
 	g_free (op);
+
+	/* for cases when this is the last reference */
+	e_mapi_utils_unref_in_thread (G_OBJECT (backend));
 }
 
 static void
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 1947d63..22a2d70 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -1277,11 +1277,18 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
 		return /* Success */;
 	}
 
-	priv->profile = g_strdup (e_source_get_property (esource, "profile"));
-	priv->user_name = g_strdup (e_source_get_property (esource, "acl-user-name"));
-	priv->user_email = g_strdup (e_source_get_property (esource, "acl-user-email"));
-	priv->owner_name = g_strdup (e_source_get_property (esource, "acl-owner-name"));
-	priv->owner_email = g_strdup (e_source_get_property (esource, "acl-owner-email"));
+	g_free (priv->profile);
+	g_free (priv->user_name);
+	g_free (priv->user_email);
+	g_free (priv->owner_name);
+	g_free (priv->owner_email);
+	g_free (priv->foreign_username);
+
+	priv->profile = e_source_get_duped_property (esource, "profile");
+	priv->user_name = e_source_get_duped_property (esource, "acl-user-name");
+	priv->user_email = e_source_get_duped_property (esource, "acl-user-email");
+	priv->owner_name = e_source_get_duped_property (esource, "acl-owner-name");
+	priv->owner_email = e_source_get_duped_property (esource, "acl-owner-email");
 
 	e_mapi_util_mapi_id_from_string (fid, &priv->fid);
 	priv->is_public_folder = g_strcmp0 (e_source_get_property (esource, "public"), "yes") == 0;
@@ -2893,8 +2900,10 @@ ecbm_operation_cb (OperationBase *op, gboolean cancelled, ECalBackend *backend)
 		g_object_unref (op->cancellable);
 	if (op->cal)
 		g_object_unref (op->cal);
-
 	g_free (op);
+
+	/* for cases when this is the last reference */
+	e_mapi_utils_unref_in_thread (G_OBJECT (backend));
 }
 
 static GSList *
@@ -2924,6 +2933,7 @@ base_op_abstract (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellabl
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -2952,6 +2962,7 @@ str_op_abstract (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -2981,6 +2992,7 @@ str2_op_abstract (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellabl
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3032,6 +3044,7 @@ ecbm_op_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *c
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3061,6 +3074,7 @@ ecbm_op_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECre
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cancellable)
 		g_object_ref (cancellable);
 
@@ -3094,6 +3108,7 @@ ecbm_op_modify_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCance
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3124,6 +3139,7 @@ ecbm_op_remove_object (ECalBackend *backend, EDataCal *cal, guint32 opid, GCance
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3155,6 +3171,7 @@ ecbm_op_discard_alarm (ECalBackend *backend, EDataCal *cal, guint32 opid, GCance
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3194,6 +3211,8 @@ ecbm_op_start_view (ECalBackend *backend, EDataCalView *view)
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
+
 	op = g_new0 (OperationStartView, 1);
 	op->base.ot = OP_START_VIEW;
 	op->view = g_object_ref (view);
@@ -3215,6 +3234,7 @@ ecbm_op_get_free_busy (ECalBackend *backend, EDataCal *cal, guint32 opid, GCance
 	priv = cbmapi->priv;
 	g_return_if_fail (priv != NULL);
 
+	g_object_ref (cbmapi);
 	if (cal)
 		g_object_ref (cal);
 	if (cancellable)
@@ -3244,6 +3264,9 @@ ecbm_dispose (GObject *object)
 	cbmapi = E_CAL_BACKEND_MAPI (object);
 	priv = cbmapi->priv;
 
+	if (priv && priv->op_queue)
+		e_mapi_operation_queue_cancel_all (priv->op_queue);
+
 	if (priv && priv->cancellable) {
 		g_cancellable_cancel (priv->cancellable);
 		g_object_unref (priv->cancellable);
@@ -3288,6 +3311,11 @@ ecbm_finalize (GObject *object)
 		priv->dthread = NULL;
 	}
 
+	if (priv->op_queue) {
+		g_object_unref (priv->op_queue);
+		priv->op_queue = NULL;
+	}
+
 	if (priv->mutex) {
 		g_mutex_free (priv->mutex);
 		priv->mutex = NULL;
@@ -3348,11 +3376,6 @@ ecbm_finalize (GObject *object)
 		priv->conn = NULL;
 	}
 
-	if (priv->op_queue) {
-		g_object_unref (priv->op_queue);
-		priv->op_queue = NULL;
-	}
-
 	g_free (priv);
 	cbmapi->priv = NULL;
 
diff --git a/src/libexchangemapi/e-mapi-utils.c b/src/libexchangemapi/e-mapi-utils.c
index 707acfa..47bf2d3 100644
--- a/src/libexchangemapi/e-mapi-utils.c
+++ b/src/libexchangemapi/e-mapi-utils.c
@@ -1251,3 +1251,31 @@ e_mapi_utils_copy_to_mapi_SPropValue (TALLOC_CTX *mem_ctx,
 
 	return FALSE;
 }
+
+static gpointer
+unref_object_in_thread (gpointer ptr)
+{
+	GObject *object = ptr;
+
+	g_return_val_if_fail (object != NULL, NULL);
+
+	g_object_unref (object);
+
+	return NULL;
+}
+
+void
+e_mapi_utils_unref_in_thread (GObject *object)
+{
+	GError *error = NULL;
+
+	if (!object)
+		return;
+
+	g_return_if_fail (G_IS_OBJECT (object));
+
+	if (!g_thread_create (unref_object_in_thread, object, FALSE, &error)) {
+		g_warning ("%s: Failed to run thread: %s", G_STRFUNC, error ? error->message : "Unknown error");
+		g_object_unref (object);
+	}
+}
diff --git a/src/libexchangemapi/e-mapi-utils.h b/src/libexchangemapi/e-mapi-utils.h
index 97d9369..1e66f70 100644
--- a/src/libexchangemapi/e-mapi-utils.h
+++ b/src/libexchangemapi/e-mapi-utils.h
@@ -125,4 +125,7 @@ gboolean	e_mapi_utils_get_folder_basic_properties_cb	(EMapiConnection *conn,
 gboolean	e_mapi_utils_copy_to_mapi_SPropValue		(TALLOC_CTX *mem_ctx,
 								 struct mapi_SPropValue *mapi_sprop, 
 								 struct SPropValue *sprop);
+
+void		e_mapi_utils_unref_in_thread			(GObject *object);
+
 #endif



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