aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/reference/libeutil/libeutil-sections.txt1
-rw-r--r--e-util/e-client-cache.c48
-rw-r--r--e-util/e-client-cache.h3
3 files changed, 52 insertions, 0 deletions
diff --git a/doc/reference/libeutil/libeutil-sections.txt b/doc/reference/libeutil/libeutil-sections.txt
index 7f092b083f..3a4d5ddd05 100644
--- a/doc/reference/libeutil/libeutil-sections.txt
+++ b/doc/reference/libeutil/libeutil-sections.txt
@@ -1260,6 +1260,7 @@ e_client_cache_get_client_sync
e_client_cache_get_client
e_client_cache_get_client_finish
e_client_cache_ref_cached_client
+e_client_cache_is_backend_dead
<SUBSECTION Standard>
E_CLIENT_CACHE
E_IS_CLIENT_CACHE
diff --git a/e-util/e-client-cache.c b/e-util/e-client-cache.c
index 3709104d09..779ae9fdc0 100644
--- a/e-util/e-client-cache.c
+++ b/e-util/e-client-cache.c
@@ -62,6 +62,7 @@ struct _ClientData {
GWeakRef cache;
EClient *client;
GQueue connecting;
+ gboolean dead_backend;
gulong backend_died_handler_id;
gulong backend_error_handler_id;
gulong notify_handler_id;
@@ -411,6 +412,14 @@ client_cache_backend_died_cb (EClient *client,
g_object_unref (cache);
}
+
+ /* Discard the EClient and tag the backend as
+ * dead until we create a replacement EClient. */
+ g_mutex_lock (&client_data->lock);
+ g_clear_object (&client_data->client);
+ client_data->dead_backend = TRUE;
+ g_mutex_unlock (&client_data->lock);
+
}
static void
@@ -495,7 +504,11 @@ client_cache_process_results (ClientData *client_data,
if (client != NULL) {
EClientCache *cache;
+ /* Make sure we're not leaking a reference. */
+ g_warn_if_fail (client_data->client == NULL);
+
client_data->client = g_object_ref (client);
+ client_data->dead_backend = FALSE;
cache = g_weak_ref_get (&client_data->cache);
@@ -1202,3 +1215,38 @@ e_client_cache_ref_cached_client (EClientCache *cache,
return client;
}
+
+/**
+ * e_client_cache_is_backend_dead:
+ * @cache: an #EClientCache
+ * @source: an #ESource
+ * @extension_name: an extension name
+ *
+ * Returns %TRUE if an #EClient instance for @source and @extension_name
+ * was recently discarded after having emitted a #EClient::backend-died
+ * signal, and a replacement #EClient instance has not yet been created.
+ *
+ * Returns: whether the backend for @source and @extension_name died
+ **/
+gboolean
+e_client_cache_is_backend_dead (EClientCache *cache,
+ ESource *source,
+ const gchar *extension_name)
+{
+ ClientData *client_data;
+ gboolean dead_backend = FALSE;
+
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (cache), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+ g_return_val_if_fail (extension_name != NULL, FALSE);
+
+ client_data = client_ht_lookup (cache, source, extension_name);
+
+ if (client_data != NULL) {
+ dead_backend = client_data->dead_backend;
+ client_data_unref (client_data);
+ }
+
+ return dead_backend;
+}
+
diff --git a/e-util/e-client-cache.h b/e-util/e-client-cache.h
index 89a70c6f65..9c92b09e18 100644
--- a/e-util/e-client-cache.h
+++ b/e-util/e-client-cache.h
@@ -102,6 +102,9 @@ EClient * e_client_cache_ref_cached_client
(EClientCache *cache,
ESource *source,
const gchar *extension_name);
+gboolean e_client_cache_is_backend_dead (EClientCache *cache,
+ ESource *source,
+ const gchar *extension_name);
G_END_DECLS