diff --git a/e-util/e-client-cache.c b/e-util/e-client-cache.c
index e468cb8..c667d52 100644
--- a/e-util/e-client-cache.c
+++ b/e-util/e-client-cache.c
@@ -43,6 +43,8 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_CLIENT_CACHE, EClientCachePrivate))
 
+static GThread *main_thread = NULL;
+
 typedef struct _ClientData ClientData;
 typedef struct _SignalClosure SignalClosure;
 
@@ -975,6 +977,10 @@ e_client_cache_init (EClientCache *client_cache)
 		E_SOURCE_EXTENSION_TASK_LIST
 	};
 
+	if (!main_thread)
+		main_thread = g_thread_self ();
+	g_print ("%s: %p: main-thread:%p\n", __FUNCTION__, client_cache, main_thread);
+
 	client_ht = g_hash_table_new_full (
 		(GHashFunc) g_str_hash,
 		(GEqualFunc) g_str_equal,
@@ -1064,11 +1070,31 @@ client_cache_get_client_sync_cb (GObject *source_object,
 
 	g_mutex_lock (&data->mutex);
 
+	g_print ("   %p %s: done for %p\n", g_thread_self (), __FUNCTION__, data->closure);
 	e_async_closure_callback (source_object, result, data->closure);
 
 	g_mutex_unlock (&data->mutex);
 }
 
+static void
+e_client_cache_get_client_sync_cancelled_cb (GCancellable *cancellable,
+					     GetClientSyncData *data)
+{
+	g_print ("      %p %s: cancelled for %p\n", g_thread_self (), __FUNCTION__, data->closure);
+}
+
+static gboolean
+client_cache_unlock_data_mutex_cb (gpointer user_data)
+{
+	GetClientSyncData *data = user_data;
+
+	g_return_val_if_fail (data != NULL, FALSE);
+
+	g_mutex_unlock (&data->mutex);
+
+	return FALSE;
+}
+
 /**
  * e_client_cache_get_client_sync:
  * @client_cache: an #EClientCache
@@ -1119,6 +1145,7 @@ e_client_cache_get_client_sync (EClientCache *client_cache,
 	GetClientSyncData data;
 	GAsyncResult *result;
 	EClient *client;
+	gulong cancel_id = 0;
 
 	g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
 	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
@@ -1127,6 +1154,14 @@ e_client_cache_get_client_sync (EClientCache *client_cache,
 	g_mutex_init (&data.mutex);
 	g_mutex_lock (&data.mutex);
 
+	g_print ("%p %s: source:%p (%s) of %s, cancellable:%p/%d good main-context:%d\n", g_thread_self (),
+		__FUNCTION__, source, e_source_get_display_name (source), extension_name,
+		cancellable, g_cancellable_is_cancelled (cancellable),
+		g_main_context_get_thread_default () == NULL || g_main_context_default () == g_main_context_get_thread_default ());
+
+	if (cancellable)
+		cancel_id = g_cancellable_connect (cancellable, G_CALLBACK (e_client_cache_get_client_sync_cancelled_cb), &data, NULL);
+
 	e_client_cache_get_client (
 		client_cache, source, extension_name,cancellable,
 		client_cache_get_client_sync_cb, &data);
@@ -1136,7 +1171,12 @@ e_client_cache_get_client_sync (EClientCache *client_cache,
 	   because that main context effectively dies at the end of this function. */
 	data.closure = e_async_closure_new ();
 
-	g_mutex_unlock (&data.mutex);
+	g_print ("   %p %s: source:%p will start wait for %p\n", g_thread_self (), __FUNCTION__, source, data.closure);
+
+	/* g_mutex_unlock (&data.mutex); is called only in the main loop of the EAsyncClosure,
+	   to have a thread safety there. */
+	g_main_context_invoke (g_main_context_get_thread_default (), client_cache_unlock_data_mutex_cb, &data);
+
 
 	result = e_async_closure_wait (data.closure);
 
@@ -1144,6 +1184,10 @@ e_client_cache_get_client_sync (EClientCache *client_cache,
 		client_cache, result, error);
 
 	g_mutex_lock (&data.mutex);
+	if (cancellable && cancel_id)
+		g_cancellable_disconnect (cancellable, cancel_id);
+
+	g_print ("   %p %s: source:%p done with wait for %p; returns client %p\n", g_thread_self (), __FUNCTION__, source, data.closure, client);
 	e_async_closure_free (data.closure);
 	g_mutex_unlock (&data.mutex);
 	g_mutex_clear (&data.mutex);
