[evolution-data-server] Add a timeout for async messages which require a reply.
- From: Chenthill Palanisamy <pchen src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Add a timeout for async messages which require a reply.
- Date: Mon, 28 Dec 2009 08:55:00 +0000 (UTC)
commit 29495ecede027a63ef21e09b3187ebe37aa21072
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Sun Dec 27 23:58:21 2009 +0530
Add a timeout for async messages which require a reply.
camel/camel-msgport.c | 24 ++++++++++++++++
camel/camel-msgport.h | 1 +
camel/providers/imapx/camel-imapx-server.c | 41 +++++++++++++++++++--------
camel/providers/imapx/camel-imapx-server.h | 3 +-
4 files changed, 56 insertions(+), 13 deletions(-)
---
diff --git a/camel/camel-msgport.c b/camel/camel-msgport.c
index 1bca3c7..affae9a 100644
--- a/camel/camel-msgport.c
+++ b/camel/camel-msgport.c
@@ -415,6 +415,30 @@ camel_msgport_try_pop (CamelMsgPort *msgport)
return msg;
}
+CamelMsg *
+camel_msgport_timed_pop (CamelMsgPort *msgport, GTimeVal *end_time)
+{
+ CamelMsg *msg;
+
+ g_return_val_if_fail (msgport != NULL, NULL);
+
+ g_async_queue_lock (msgport->queue);
+
+ msg = g_async_queue_timed_pop_unlocked (msgport->queue, end_time);
+
+ if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PIPE)
+ msgport_sync_with_pipe (msgport->pipe[0]);
+#ifdef HAVE_NSS
+ if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PR_PIPE)
+ msgport_sync_with_prpipe (msgport->prpipe[0]);
+#endif
+
+ g_async_queue_unlock (msgport->queue);
+
+ return msg;
+}
+
+
void
camel_msgport_reply (CamelMsg *msg)
{
diff --git a/camel/camel-msgport.h b/camel/camel-msgport.h
index 30f1891..311054b 100644
--- a/camel/camel-msgport.h
+++ b/camel/camel-msgport.h
@@ -42,6 +42,7 @@ void camel_msgport_push (CamelMsgPort *msgport,
CamelMsg *msg);
CamelMsg * camel_msgport_pop (CamelMsgPort *msgport);
CamelMsg * camel_msgport_try_pop (CamelMsgPort *msgport);
+CamelMsg * camel_msgport_timed_pop (CamelMsgPort *msgport, GTimeVal *end_time);
void camel_msgport_reply (CamelMsg *msg);
#ifdef HAVE_NSS
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 16a0c4c..917bb53 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2441,6 +2441,7 @@ cancel_all_jobs (CamelIMAPXServer *is)
camel_dlist_remove ((CamelDListNode *)cw);
cw->status = create_cancel_status ();
+ camel_exception_set (cw->job->ex, CAMEL_EXCEPTION_USER_CANCEL, "Operation Cancelled");
cw->complete (is, cw);
camel_imapx_command_free (cw);
@@ -2504,6 +2505,7 @@ imapx_server_loop(gpointer d)
/* if ssl stream ... */
#ifdef HAVE_SSL
+ if (CAMEL_IS_TCP_STREAM_SSL (is->stream->source))
{
PRPollDesc pollfds[2] = { };
gint res;
@@ -2528,8 +2530,9 @@ imapx_server_loop(gpointer d)
errno = EINTR;
}
}
-#else
+#endif
+ if (!CAMEL_IS_TCP_STREAM_SSL (is->stream->source))
{
struct pollfd fds[2] = { {0, 0, 0}, {0, 0, 0} };
gint res;
@@ -2552,7 +2555,7 @@ imapx_server_loop(gpointer d)
errno = EINTR;
}
}
-#endif
+
if (errno == EINTR)
camel_exception_setv (&ex, CAMEL_EXCEPTION_USER_CANCEL, "Operation Cancelled: %s", g_strerror(errno));
@@ -2592,6 +2595,8 @@ imapx_server_init(CamelIMAPXServer *ie, CamelIMAPXServerClass *ieclass)
camel_dlist_init(&ie->active);
camel_dlist_init(&ie->done);
camel_dlist_init(&ie->jobs);
+
+ ie->job_timeout = 20 * 1000 * 1000;
ie->queue_lock = g_mutex_new();
ie->connect_lock = g_mutex_new ();
@@ -2715,7 +2720,7 @@ imapx_run_job(CamelIMAPXServer *is, CamelIMAPXJob *job)
CamelMsgPort *reply;
if (!job->noreply) {
- reply = camel_msgport_new();
+ reply = camel_msgport_new ();
job->msg.reply_port = reply;
}
@@ -2723,23 +2728,35 @@ imapx_run_job(CamelIMAPXServer *is, CamelIMAPXJob *job)
we can't read from this thread ... hrm ... */
if (is->state >= IMAPX_AUTHENTICATED) {
/* NB: Must catch exceptions, cleanup/etc if we fail here? */
- QUEUE_LOCK(is);
- camel_dlist_addhead(&is->jobs, (CamelDListNode *)job);
- QUEUE_UNLOCK(is);
- job->start(is, job);
+ QUEUE_LOCK (is);
+ camel_dlist_addhead (&is->jobs, (CamelDListNode *)job);
+ QUEUE_UNLOCK (is);
+ job->start (is, job);
} else {
camel_msgport_push (is->port, (CamelMsg *)job);
}
if (!job->noreply) {
- CamelMsg *completed = camel_msgport_pop (reply);
+ GTimeVal end_time;
+ CamelMsg *completed;
+
+ g_get_current_time (&end_time);
+ g_time_val_add (&end_time, is->job_timeout);
+
+ completed = camel_msgport_timed_pop (reply, &end_time);
+ camel_msgport_destroy (reply);
+
+ if (completed == NULL) {
+ camel_exception_set (job->ex, 1, "Operation timed out" );
+ return;
+ }
+
g_assert(completed == (CamelMsg *)job);
- camel_msgport_destroy(reply);
}
}
static CamelStream *
-imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, gint pri, CamelException *ex)
+imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, gint pri, CamelException *ex)
{
CamelStream *stream;
CamelIMAPXJob *job;
@@ -2753,8 +2770,8 @@ imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const gchar
which handles concurrent adds properly.
EXCEPT! It wont handle the 'new' dir directly ... do we care? */
- name = imapx_get_path_uid(is, folder, NULL, uid);
- stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0);
+ name = imapx_get_path_uid (is, folder, NULL, uid);
+ stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0);
if (stream) {
g_free(name);
return stream;
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 7d7579c..4bd6b65 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -56,6 +56,8 @@ struct _CamelIMAPXServer {
/* incoming jobs */
CamelMsgPort *port;
CamelDList jobs;
+ /* in micro seconds */
+ guint job_timeout;
gchar tagprefix;
gint state:4;
@@ -86,7 +88,6 @@ struct _CamelIMAPXServer {
GMutex *connect_lock;
pthread_t parser_thread_id;
- gboolean disconnect;
};
struct _CamelIMAPXServerClass {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]