[evolution-data-server/gnome-3-8] CamelIMAPXServer: Rewrite duplicate message fetching.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-8] CamelIMAPXServer: Rewrite duplicate message fetching.
- Date: Mon, 8 Apr 2013 18:44:24 +0000 (UTC)
commit daf4b3e7f6d284ed7548fbd390b4b1eba88d21ec
Author: Matthew Barnes <mbarnes redhat com>
Date: Mon Apr 8 14:09:13 2013 -0400
CamelIMAPXServer: Rewrite duplicate message fetching.
The g_cond_wait() call in imapx_server_get_message() seems to be the
source of many deadlocks. Possibly because some of the error handling
branches in that function fail to broadcast the GCond being waited on,
and cancellation is a very common error condition, especially when the
user is rapidly browsing through messages.
The code is attempting to wait for the completion of a GET_MESSAGE job
for the same UID which is already queued. It's doing this by defining
its own GMutex and GCond, but it turns out we already have a function
for this: camel_imapx_job_wait().
Let's try using camel_imapx_job_wait() there. It can't do worse than
the current situation, and we can kill off the specialized GMutex and
GCond variables which were unfortunately made public.
(cherry picked from commit 4a1025dd38ba57725b2c147f8b791f05eb577b72)
camel/camel-imapx-server.c | 36 +++++-------------------------------
camel/camel-imapx-server.h | 5 -----
2 files changed, 5 insertions(+), 36 deletions(-)
---
diff --git a/camel/camel-imapx-server.c b/camel/camel-imapx-server.c
index eeedd6a..87e5c91 100644
--- a/camel/camel-imapx-server.c
+++ b/camel/camel-imapx-server.c
@@ -7166,8 +7166,6 @@ imapx_server_finalize (GObject *object)
g_rec_mutex_clear (&is->queue_lock);
g_mutex_clear (&is->select_lock);
- g_mutex_clear (&is->fetch_mutex);
- g_cond_clear (&is->fetch_cond);
camel_folder_change_info_free (is->changes);
@@ -7299,9 +7297,6 @@ camel_imapx_server_init (CamelIMAPXServer *is)
is->changes = camel_folder_change_info_new ();
is->parser_quit = FALSE;
- g_mutex_init (&is->fetch_mutex);
- g_cond_init (&is->fetch_cond);
-
is->priv->known_alerts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
@@ -7432,32 +7427,16 @@ imapx_server_get_message (CamelIMAPXServer *is,
QUEUE_LOCK (is);
if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_GET_MESSAGE, uid))) {
+ /* Promote the existing GET_MESSAGE
+ * job's priority if ours is higher. */
if (pri > job->pri)
job->pri = pri;
- /* Wait for the job to finish. This would be so much nicer if
- * we could just use the queue lock with a GCond, but instead
- * we have to use a GMutex. I miss the kernel waitqueues. */
- do {
- gint this;
-
- g_mutex_lock (&is->fetch_mutex);
- this = is->fetch_count;
-
- QUEUE_UNLOCK (is);
-
- while (is->fetch_count == this)
- g_cond_wait (&is->fetch_cond, &is->fetch_mutex);
-
- g_mutex_unlock (&is->fetch_mutex);
-
- QUEUE_LOCK (is);
-
- } while (imapx_is_job_in_queue (is, folder,
- IMAPX_JOB_GET_MESSAGE, uid));
-
QUEUE_UNLOCK (is);
+ /* Wait for the job to finish. */
+ camel_imapx_job_wait (job);
+
stream = camel_data_cache_get (
ifolder->cache, "cur", uid, error);
if (stream == NULL)
@@ -7507,11 +7486,6 @@ imapx_server_get_message (CamelIMAPXServer *is,
camel_imapx_job_unref (job);
- g_mutex_lock (&is->fetch_mutex);
- is->fetch_count++;
- g_cond_broadcast (&is->fetch_cond);
- g_mutex_unlock (&is->fetch_mutex);
-
return stream;
}
diff --git a/camel/camel-imapx-server.h b/camel/camel-imapx-server.h
index b23447e..f931265 100644
--- a/camel/camel-imapx-server.h
+++ b/camel/camel-imapx-server.h
@@ -159,11 +159,6 @@ struct _CamelIMAPXServer {
gboolean use_idle;
gboolean use_qresync;
-
- /* used to synchronize duplicate get_message requests */
- GCond fetch_cond;
- GMutex fetch_mutex;
- gint fetch_count;
};
struct _CamelIMAPXServerClass {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]