[evolution/wip/webkit2] Use own thread pool for WebKit content download
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Use own thread pool for WebKit content download
- Date: Wed, 24 Feb 2016 10:31:19 +0000 (UTC)
commit a704671e49dd9b12dd6f28341d9da5e8dcca3b37
Author: Milan Crha <mcrha redhat com>
Date: Fri Apr 3 08:22:10 2015 +0200
Use own thread pool for WebKit content download
Mails with many images (remote content in general) could block GTask's
thread pool for a long time, making starve other requests. Adding our
own thread pool avoids such job starving.
e-util/e-misc-utils.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
e-util/e-misc-utils.h | 4 ++
mail/e-http-request.c | 4 +-
mail/e-mail-request.c | 4 +-
4 files changed, 82 insertions(+), 4 deletions(-)
---
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index ff53bbc..9da55f3 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -3179,3 +3179,77 @@ e_util_prompt_user (GtkWindow *parent,
return button == GTK_RESPONSE_YES;
}
+
+typedef struct _EUtilSimpleAsyncResultThreadData {
+ GSimpleAsyncResult *simple;
+ GSimpleAsyncThreadFunc func;
+ GCancellable *cancellable;
+} EUtilSimpleAsyncResultThreadData;
+
+static void
+e_util_simple_async_result_thread (gpointer data,
+ gpointer user_data)
+{
+ EUtilSimpleAsyncResultThreadData *thread_data = data;
+ GError *error = NULL;
+
+ g_return_if_fail (thread_data != NULL);
+ g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (thread_data->simple));
+ g_return_if_fail (thread_data->func != NULL);
+
+ if (g_cancellable_set_error_if_cancelled (thread_data->cancellable, &error)) {
+ g_simple_async_result_take_error (thread_data->simple, error);
+ } else {
+ thread_data->func (thread_data->simple,
+ g_async_result_get_source_object (G_ASYNC_RESULT (thread_data->simple)),
+ thread_data->cancellable);
+ }
+
+ g_simple_async_result_complete_in_idle (thread_data->simple);
+
+ g_clear_object (&thread_data->simple);
+ g_clear_object (&thread_data->cancellable);
+ g_free (thread_data);
+}
+
+/**
+ * e_util_run_simple_async_result_in_thread:
+ * @simple: a #GSimpleAsyncResult
+ * @func: a #GSimpleAsyncThreadFunc to execute in the thread
+ * @cancellable: an optional #GCancellable, or %NULL
+ *
+ * Similar to g_simple_async_result_run_in_thread(), except
+ * it doesn't use GTask internally, thus doesn't block the GTask
+ * thread pool with possibly long job.
+ *
+ * It doesn't behave exactly the same as the g_simple_async_result_run_in_thread(),
+ * the @cancellable checking is not done before the finish.
+ *
+ * Since: 3.18
+ **/
+void
+e_util_run_simple_async_result_in_thread (GSimpleAsyncResult *simple,
+ GSimpleAsyncThreadFunc func,
+ GCancellable *cancellable)
+{
+ static GThreadPool *thread_pool = NULL;
+ static GMutex thread_pool_mutex;
+ EUtilSimpleAsyncResultThreadData *thread_data;
+
+ g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
+ g_return_if_fail (func != NULL);
+
+ g_mutex_lock (&thread_pool_mutex);
+
+ if (!thread_pool)
+ thread_pool = g_thread_pool_new (e_util_simple_async_result_thread, NULL, 20, FALSE, NULL);
+
+ thread_data = g_new0 (EUtilSimpleAsyncResultThreadData, 1);
+ thread_data->simple = g_object_ref (simple);
+ thread_data->func = func;
+ thread_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+
+ g_thread_pool_push (thread_pool, thread_data, NULL);
+
+ g_mutex_unlock (&thread_pool_mutex);
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index b7ef19d..b4d9faa 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -277,6 +277,10 @@ gboolean e_util_prompt_user (GtkWindow *parent,
const gchar *promptkey,
const gchar *tag,
...);
+void e_util_run_simple_async_result_in_thread
+ (GSimpleAsyncResult *simple,
+ GSimpleAsyncThreadFunc func,
+ GCancellable *cancellable);
guint e_util_normalize_font_size (GtkWidget *widget,
gdouble font_size);
diff --git a/mail/e-http-request.c b/mail/e-http-request.c
index 97cd9c9..f59d26c 100644
--- a/mail/e-http-request.c
+++ b/mail/e-http-request.c
@@ -522,9 +522,9 @@ http_request_send_async (SoupRequest *request,
g_simple_async_result_set_check_cancellable (simple, cancellable);
- g_simple_async_result_run_in_thread (
+ e_util_run_simple_async_result_in_thread (
simple, handle_http_request,
- G_PRIORITY_DEFAULT, cancellable);
+ cancellable);
g_object_unref (simple);
}
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index f11b3be..9a97f4f 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -362,9 +362,9 @@ mail_request_send_async (SoupRequest *request,
g_simple_async_result_set_check_cancellable (simple, cancellable);
if (g_strcmp0 (uri->host, "contact-photo") == 0) {
- g_simple_async_result_run_in_thread (
+ e_util_run_simple_async_result_in_thread (
simple, handle_contact_photo_request,
- G_PRIORITY_DEFAULT, cancellable);
+ cancellable);
} else {
/* Process e-mail mail requests in this thread, which should be
* the main/UI thread, because any EMailFormatter can create
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]