[evolution-ews] EEwsPhotoSource: Do not use GTask thread pool, but use its own serialized pool
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] EEwsPhotoSource: Do not use GTask thread pool, but use its own serialized pool
- Date: Tue, 11 Oct 2022 15:18:30 +0000 (UTC)
commit 34a27dcb18a4eca42f4fa501bbce46d705fd3f30
Author: Milan Crha <mcrha redhat com>
Date: Tue Oct 11 17:15:52 2022 +0200
EEwsPhotoSource: Do not use GTask thread pool, but use its own serialized pool
The GTask thread pool should not be used for long standing tasks, because
such tasks can cause starving of follow up GTask-s in certain situations.
Also serialize photo lookup requests, processing one at a time, to avoid
the same GTask thread pool overuse on the EEwsConnection side.
src/EWS/evolution/e-ews-photo-source.c | 37 +++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
---
diff --git a/src/EWS/evolution/e-ews-photo-source.c b/src/EWS/evolution/e-ews-photo-source.c
index b58dc8c1..27812c1a 100644
--- a/src/EWS/evolution/e-ews-photo-source.c
+++ b/src/EWS/evolution/e-ews-photo-source.c
@@ -37,6 +37,7 @@ typedef struct _EEwsPhotoSourceClass EEwsPhotoSourceClass;
struct _EEwsPhotoSource {
EExtension parent;
+ GThreadPool *pool;
};
struct _EEwsPhotoSourceClass {
@@ -51,12 +52,12 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (EEwsPhotoSource, e_ews_photo_source, E_TYPE_EXTE
G_IMPLEMENT_INTERFACE_DYNAMIC (E_TYPE_PHOTO_SOURCE, ews_photo_source_iface_init))
static void
-ews_photo_source_thread (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+e_ews_photo_source_pool_thread_func_cb (gpointer data,
+ gpointer user_data)
{
- const gchar *email_address = task_data;
+ GTask *task = data;
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ const gchar *email_address = g_task_get_task_data (task);
GSList *connections, *link;
GHashTable *covered_uris;
GError *local_error = NULL;
@@ -66,7 +67,7 @@ ews_photo_source_thread (GTask *task,
covered_uris = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL);
connections = e_ews_connection_list_existing ();
- for (link = connections; link; link = g_slist_next (link)) {
+ for (link = connections; link && !g_cancellable_is_cancelled (cancellable); link = g_slist_next
(link)) {
EEwsConnection *cnc = link->data;
gchar *picture_data = NULL;
const gchar *uri;
@@ -94,7 +95,7 @@ ews_photo_source_thread (GTask *task,
decoded = NULL;
g_task_return_pointer (task, stream, g_object_unref);
- task = NULL;
+ g_clear_object (&task);
g_free (decoded);
break;
}
@@ -113,6 +114,7 @@ ews_photo_source_thread (GTask *task,
}
g_task_return_error (task, local_error);
+ g_clear_object (&task);
} else {
g_clear_error (&local_error);
}
@@ -125,16 +127,20 @@ ews_photo_source_get_photo (EPhotoSource *photo_source,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ EEwsPhotoSource *ews_photo_source;
GTask *task;
g_return_if_fail (E_IS_EWS_PHOTO_SOURCE (photo_source));
g_return_if_fail (email_address != NULL);
+ ews_photo_source = E_EWS_PHOTO_SOURCE (photo_source);
+
task = g_task_new (photo_source, cancellable, callback, user_data);
g_task_set_source_tag (task, ews_photo_source_get_photo);
g_task_set_task_data (task, g_strdup (email_address), g_free);
- g_task_run_in_thread (task, ews_photo_source_thread);
- g_object_unref (task);
+ /* process only one request at a time, without using GTask threads, because
+ those are important to not be used for a long time */
+ g_thread_pool_push (ews_photo_source->pool, task, NULL);
}
static gboolean
@@ -178,6 +184,17 @@ ews_photo_source_constructed (GObject *object)
e_photo_cache_add_photo_source (photo_cache, E_PHOTO_SOURCE (object));
}
+static void
+ews_photo_source_finalize (GObject *object)
+{
+ EEwsPhotoSource *ews_photo_source = E_EWS_PHOTO_SOURCE (object);
+
+ g_thread_pool_free (ews_photo_source->pool, FALSE, TRUE);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_ews_photo_source_parent_class)->finalize (object);
+}
+
static void
e_ews_photo_source_class_init (EEwsPhotoSourceClass *class)
{
@@ -186,6 +203,7 @@ e_ews_photo_source_class_init (EEwsPhotoSourceClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->constructed = ews_photo_source_constructed;
+ object_class->finalize = ews_photo_source_finalize;
extension_class = E_EXTENSION_CLASS (class);
extension_class->extensible_type = E_TYPE_PHOTO_CACHE;
@@ -206,6 +224,7 @@ ews_photo_source_iface_init (EPhotoSourceInterface *iface)
static void
e_ews_photo_source_init (EEwsPhotoSource *extension)
{
+ extension->pool = g_thread_pool_new (e_ews_photo_source_pool_thread_func_cb, NULL, 1, FALSE, NULL);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]