[evolution-data-server/gnome-2-30] Fix idle thread exit and locking
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-2-30] Fix idle thread exit and locking
- Date: Mon, 28 Jun 2010 19:37:18 +0000 (UTC)
commit 13557c29ce41064a2850bb3f1e0d3c84a23d79d8
Author: David Woodhouse <David Woodhouse intel com>
Date: Fri Jun 25 18:09:09 2010 +0100
Fix idle thread exit and locking
If we trigger its exit and wait for it while still holding the lock, it may
deadlock on the same lock. Also fix a multiple-unlock bug.
(cherry picked from commit ab8442ff77654a54cd6556bc73533bc386408c60)
camel/providers/imapx/camel-imapx-server.c | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 7b1c815..01449fc 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2054,16 +2054,19 @@ imapx_idle_thread (gpointer data)
while (TRUE) {
CamelIMAPXFolder *ifolder;
+
e_flag_clear (is->idle->idle_start_watch);
IDLE_LOCK(is->idle);
while ((ifolder = (CamelIMAPXFolder *) is->select_folder) &&
- is->idle->state == IMAPX_IDLE_PENDING) {
+ is->idle->state == IMAPX_IDLE_PENDING &&
+ !is->idle->idle_exit) {
time_t dwelled = time(NULL) - is->idle->started;
if (dwelled < IMAPX_IDLE_DWELL_TIME) {
IDLE_UNLOCK(is->idle);
g_usleep((IMAPX_IDLE_DWELL_TIME - dwelled) * G_USEC_PER_SEC);
+ IDLE_LOCK(is->idle);
continue;
}
IDLE_UNLOCK(is->idle);
@@ -2078,6 +2081,7 @@ imapx_idle_thread (gpointer data)
/* No way to asyncronously notify UI ? */
camel_exception_clear (ex);
}
+ IDLE_LOCK(is->idle);
}
IDLE_UNLOCK(is->idle);
@@ -2136,6 +2140,7 @@ static void
imapx_exit_idle (CamelIMAPXServer *is)
{
CamelIMAPXIdle *idle = is->idle;
+ GThread *thread = NULL;
if (!idle)
return;
@@ -2146,13 +2151,16 @@ imapx_exit_idle (CamelIMAPXServer *is)
idle->idle_exit = TRUE;
e_flag_set (idle->idle_start_watch);
- if (idle->idle_thread)
- g_thread_join (idle->idle_thread);
+ thread = idle->idle_thread;
+ idle->idle_thread = 0;
}
idle->idle_thread = NULL;
IDLE_UNLOCK (idle);
+ if (thread)
+ g_thread_join (thread);
+
g_mutex_free (idle->idle_lock);
if (idle->idle_start_watch)
e_flag_free (idle->idle_start_watch);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]