[evolution-data-server] CamelIMAPXJob: Make imapx_job_run() more responsive to cancellations.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelIMAPXJob: Make imapx_job_run() more responsive to cancellations.
- Date: Fri, 2 Dec 2011 06:17:48 +0000 (UTC)
commit 28284e3802e95616c36dc64d7d8924829ba7bf37
Author: Matthew Barnes <mbarnes redhat com>
Date: Thu Dec 1 21:00:16 2011 -0600
CamelIMAPXJob: Make imapx_job_run() more responsive to cancellations.
Connect a GCancellable::cancelled signal handler that broadcasts the
GCond that imapx_job_run() is waiting on so it can proceed immediately.
If imapx_job_done() is called sometime later by the thread executing the
job, the GCond will broadcast again but no one will be listening for it.
Giving CamelIMAPXJob a reference count allows the imapx_job_run() caller
to drop its job reference and proceed without worrying about whether the
job is still active in the parser thread, since the parser thread will
have its own job reference.
camel/providers/imapx/camel-imapx-server.c | 30 ++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 87aedc4..724785b 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2255,6 +2255,21 @@ imapx_job_done (CamelIMAPXServer *is,
QUEUE_UNLOCK (is);
}
+static void
+imapx_job_cancelled (GCancellable *cancellable,
+ CamelIMAPXJob *job)
+{
+ /* Unblock imapx_run_job() immediately.
+ *
+ * If imapx_job_done() is called sometime later, the
+ * GCond will broadcast but no one will be listening. */
+
+ g_mutex_lock (job->done_mutex);
+ job->done_flag = TRUE;
+ g_cond_broadcast (job->done_cond);
+ g_mutex_unlock (job->done_mutex);
+}
+
static gboolean
imapx_register_job (CamelIMAPXServer *is,
CamelIMAPXJob *job,
@@ -2282,11 +2297,20 @@ imapx_run_job (CamelIMAPXServer *is,
CamelIMAPXJob *job,
GError **error)
{
+ gulong cancel_id;
+
g_warn_if_fail (job->done_flag == FALSE);
if (g_cancellable_set_error_if_cancelled (is->cancellable, error))
return FALSE;
+ if (G_IS_CANCELLABLE (job->cancellable))
+ cancel_id = g_cancellable_connect (
+ job->cancellable,
+ G_CALLBACK (imapx_job_cancelled),
+ imapx_job_ref (job),
+ (GDestroyNotify) imapx_job_unref);
+
job->start (is, job);
if (!job->noreply) {
@@ -2296,6 +2320,12 @@ imapx_run_job (CamelIMAPXServer *is,
g_mutex_unlock (job->done_mutex);
}
+ if (cancel_id > 0)
+ g_cancellable_disconnect (job->cancellable, cancel_id);
+
+ if (g_cancellable_set_error_if_cancelled (job->cancellable, error))
+ return FALSE;
+
if (job->error != NULL) {
g_propagate_error (error, job->error);
job->error = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]