|
|
5e6360 |
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c
|
|
|
5e6360 |
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-empty-cache-file-temp-workaround 2014-06-16 15:00:03.000000000 +0200
|
|
|
5e6360 |
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c 2015-05-26 15:02:30.395243456 +0200
|
|
|
5e6360 |
@@ -182,6 +182,7 @@ camel_imapx_job_wait (CamelIMAPXJob *job
|
|
|
5e6360 |
{
|
|
|
5e6360 |
CamelIMAPXRealJob *real_job;
|
|
|
5e6360 |
GCancellable *cancellable;
|
|
|
5e6360 |
+ gulong cancel_id = 0;
|
|
|
5e6360 |
gboolean success = TRUE;
|
|
|
5e6360 |
|
|
|
5e6360 |
g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
|
|
|
5e6360 |
@@ -189,13 +190,23 @@ camel_imapx_job_wait (CamelIMAPXJob *job
|
|
|
5e6360 |
real_job = (CamelIMAPXRealJob *) job;
|
|
|
5e6360 |
cancellable = camel_imapx_job_get_cancellable (job);
|
|
|
5e6360 |
|
|
|
5e6360 |
+ if (G_IS_CANCELLABLE (cancellable))
|
|
|
5e6360 |
+ cancel_id = g_cancellable_connect (
|
|
|
5e6360 |
+ cancellable,
|
|
|
5e6360 |
+ G_CALLBACK (imapx_job_cancelled_cb),
|
|
|
5e6360 |
+ camel_imapx_job_ref (job),
|
|
|
5e6360 |
+ (GDestroyNotify) camel_imapx_job_unref);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
g_mutex_lock (&real_job->done_mutex);
|
|
|
5e6360 |
- while (!real_job->done_flag)
|
|
|
5e6360 |
+ while (!real_job->done_flag && !g_cancellable_is_cancelled (cancellable))
|
|
|
5e6360 |
g_cond_wait (
|
|
|
5e6360 |
&real_job->done_cond,
|
|
|
5e6360 |
&real_job->done_mutex);
|
|
|
5e6360 |
g_mutex_unlock (&real_job->done_mutex);
|
|
|
5e6360 |
|
|
|
5e6360 |
+ if (cancel_id > 0)
|
|
|
5e6360 |
+ g_cancellable_disconnect (cancellable, cancel_id);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
/* Cancellation takes priority over other errors. */
|
|
|
5e6360 |
if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
|
|
|
5e6360 |
success = FALSE;
|
|
|
5e6360 |
@@ -233,7 +244,6 @@ camel_imapx_job_run (CamelIMAPXJob *job,
|
|
|
5e6360 |
GError **error)
|
|
|
5e6360 |
{
|
|
|
5e6360 |
GCancellable *cancellable;
|
|
|
5e6360 |
- gulong cancel_id = 0;
|
|
|
5e6360 |
gboolean success;
|
|
|
5e6360 |
|
|
|
5e6360 |
g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
|
|
|
5e6360 |
@@ -245,21 +255,11 @@ camel_imapx_job_run (CamelIMAPXJob *job,
|
|
|
5e6360 |
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
|
|
5e6360 |
return FALSE;
|
|
|
5e6360 |
|
|
|
5e6360 |
- if (G_IS_CANCELLABLE (cancellable))
|
|
|
5e6360 |
- cancel_id = g_cancellable_connect (
|
|
|
5e6360 |
- cancellable,
|
|
|
5e6360 |
- G_CALLBACK (imapx_job_cancelled_cb),
|
|
|
5e6360 |
- camel_imapx_job_ref (job),
|
|
|
5e6360 |
- (GDestroyNotify) camel_imapx_job_unref);
|
|
|
5e6360 |
-
|
|
|
5e6360 |
success = job->start (job, is, cancellable, error);
|
|
|
5e6360 |
|
|
|
5e6360 |
if (success && !job->noreply)
|
|
|
5e6360 |
success = camel_imapx_job_wait (job, error);
|
|
|
5e6360 |
|
|
|
5e6360 |
- if (cancel_id > 0)
|
|
|
5e6360 |
- g_cancellable_disconnect (cancellable, cancel_id);
|
|
|
5e6360 |
-
|
|
|
5e6360 |
return success;
|
|
|
5e6360 |
}
|
|
|
5e6360 |
|
|
|
5e6360 |
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c
|
|
|
5e6360 |
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-empty-cache-file-temp-workaround 2015-05-26 15:02:30.390243457 +0200
|
|
|
5e6360 |
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c 2015-05-26 15:02:46.146242702 +0200
|
|
|
5e6360 |
@@ -57,8 +57,8 @@
|
|
|
5e6360 |
#define c(...) camel_imapx_debug(command, __VA_ARGS__)
|
|
|
5e6360 |
#define e(...) camel_imapx_debug(extra, __VA_ARGS__)
|
|
|
5e6360 |
|
|
|
5e6360 |
-#define QUEUE_LOCK(x) (g_rec_mutex_lock(&(x)->queue_lock))
|
|
|
5e6360 |
-#define QUEUE_UNLOCK(x) (g_rec_mutex_unlock(&(x)->queue_lock))
|
|
|
5e6360 |
+#define QUEUE_LOCK(x) g_rec_mutex_lock (&(x)->queue_lock)
|
|
|
5e6360 |
+#define QUEUE_UNLOCK(x) g_rec_mutex_unlock (&(x)->queue_lock)
|
|
|
5e6360 |
|
|
|
5e6360 |
/* Try pipelining fetch requests, 'in bits' */
|
|
|
5e6360 |
#define MULTI_SIZE (32768 * 8)
|
|
|
5e6360 |
@@ -5172,23 +5172,54 @@ imapx_command_fetch_message_done (CamelI
|
|
|
5e6360 |
g_free (tmp_filename);
|
|
|
5e6360 |
}
|
|
|
5e6360 |
|
|
|
5e6360 |
- /* Delete the 'tmp' file only if the operation wasn't cancelled. It's because
|
|
|
5e6360 |
+ /* Delete the 'tmp' file only if the operation succeeded. It's because
|
|
|
5e6360 |
cancelled operations end before they are properly finished (IMAP-protocol speaking),
|
|
|
5e6360 |
thus if any other GET_MESSAGE operation was waiting for this job, then it
|
|
|
5e6360 |
realized that the message was not downloaded and opened its own "tmp" file, but
|
|
|
5e6360 |
of the same name, thus this remove would drop file which could be used
|
|
|
5e6360 |
by a different GET_MESSAGE job. */
|
|
|
5e6360 |
- if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
5e6360 |
+ if (!local_error && !g_cancellable_is_cancelled (cancellable))
|
|
|
5e6360 |
camel_data_cache_remove (data->message_cache, "tmp", data->uid, NULL);
|
|
|
5e6360 |
|
|
|
5e6360 |
/* Avoid possible use-after-free when the imapx_unregister_job() can
|
|
|
5e6360 |
also free the 'job' structure. */
|
|
|
5e6360 |
+ camel_imapx_job_ref (job);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ imapx_unregister_job (is, job);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
if (local_error != NULL) {
|
|
|
5e6360 |
- camel_imapx_job_take_error (job, local_error);
|
|
|
5e6360 |
- local_error = NULL;
|
|
|
5e6360 |
+ CamelIMAPXJob *pending_job;
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ /* Give a chance to other threads. */
|
|
|
5e6360 |
+ g_thread_yield ();
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ pending_job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, data->uid);
|
|
|
5e6360 |
+ if (pending_job != NULL) {
|
|
|
5e6360 |
+ GIOStream *cache_stream;
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ /* Wait for the job to finish. */
|
|
|
5e6360 |
+ camel_imapx_job_wait (pending_job, NULL);
|
|
|
5e6360 |
+ camel_imapx_job_unref (pending_job);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ /* Disregard errors here. If we failed to retrieve the
|
|
|
5e6360 |
+ * message from cache (implying the job we were waiting
|
|
|
5e6360 |
+ * on failed or got cancelled), we'll just re-fetch it. */
|
|
|
5e6360 |
+ cache_stream = camel_data_cache_get (data->message_cache, "cur", data->uid, NULL);
|
|
|
5e6360 |
+ if (cache_stream != NULL) {
|
|
|
5e6360 |
+ g_clear_error (&local_error);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ g_clear_object (&data->stream);
|
|
|
5e6360 |
+ data->stream = cache_stream;
|
|
|
5e6360 |
+ }
|
|
|
5e6360 |
+ }
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ if (local_error) {
|
|
|
5e6360 |
+ camel_imapx_job_take_error (job, local_error);
|
|
|
5e6360 |
+ local_error = NULL;
|
|
|
5e6360 |
+ }
|
|
|
5e6360 |
}
|
|
|
5e6360 |
|
|
|
5e6360 |
- imapx_unregister_job (is, job);
|
|
|
5e6360 |
+ camel_imapx_job_unref (job);
|
|
|
5e6360 |
|
|
|
5e6360 |
exit:
|
|
|
5e6360 |
if (local_error != NULL)
|
|
|
5e6360 |
@@ -8344,9 +8375,7 @@ imapx_server_get_message (CamelIMAPXServ
|
|
|
5e6360 |
GetMessageData *data;
|
|
|
5e6360 |
gboolean registered;
|
|
|
5e6360 |
|
|
|
5e6360 |
- job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid);
|
|
|
5e6360 |
-
|
|
|
5e6360 |
- if (job != NULL) {
|
|
|
5e6360 |
+ while (job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid), job != NULL) {
|
|
|
5e6360 |
/* Promote the existing GET_MESSAGE
|
|
|
5e6360 |
* job's priority if ours is higher. */
|
|
|
5e6360 |
if (pri > job->pri)
|
|
|
5e6360 |
@@ -8362,14 +8391,26 @@ imapx_server_get_message (CamelIMAPXServ
|
|
|
5e6360 |
cache_stream = camel_data_cache_get (
|
|
|
5e6360 |
message_cache, "cur", message_uid, NULL);
|
|
|
5e6360 |
if (cache_stream != NULL) {
|
|
|
5e6360 |
- stream = camel_stream_new (cache_stream);
|
|
|
5e6360 |
+ /* Return new file stream, instead of a DataCache's to not fight
|
|
|
5e6360 |
+ on its content and position with other jobs, if any. */
|
|
|
5e6360 |
+ gchar *filename = camel_data_cache_get_filename (message_cache, "cur", message_uid);
|
|
|
5e6360 |
+ stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL);
|
|
|
5e6360 |
+ g_free (filename);
|
|
|
5e6360 |
g_object_unref (cache_stream);
|
|
|
5e6360 |
- return stream;
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ if (stream)
|
|
|
5e6360 |
+ return stream;
|
|
|
5e6360 |
}
|
|
|
5e6360 |
}
|
|
|
5e6360 |
|
|
|
5e6360 |
QUEUE_LOCK (is);
|
|
|
5e6360 |
|
|
|
5e6360 |
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
|
|
|
5e6360 |
+ QUEUE_UNLOCK (is);
|
|
|
5e6360 |
+
|
|
|
5e6360 |
+ return NULL;
|
|
|
5e6360 |
+ }
|
|
|
5e6360 |
+
|
|
|
5e6360 |
mi = camel_folder_summary_get (summary, message_uid);
|
|
|
5e6360 |
if (mi == NULL) {
|
|
|
5e6360 |
g_set_error (
|
|
|
5e6360 |
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.h.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.h
|
|
|
5e6360 |
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c
|
|
|
5e6360 |
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c.imapx-empty-cache-file-temp-workaround 2014-12-02 16:07:54.000000000 +0100
|
|
|
5e6360 |
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c 2015-05-26 15:02:46.148242702 +0200
|
|
|
5e6360 |
@@ -704,7 +704,6 @@ imapx_store_finalize (GObject *object)
|
|
|
5e6360 |
priv = CAMEL_IMAPX_STORE_GET_PRIVATE (object);
|
|
|
5e6360 |
|
|
|
5e6360 |
g_mutex_clear (&priv->get_finfo_lock);
|
|
|
5e6360 |
-
|
|
|
5e6360 |
g_mutex_clear (&priv->server_lock);
|
|
|
5e6360 |
|
|
|
5e6360 |
g_hash_table_destroy (priv->quota_info);
|
|
|
5e6360 |
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.h.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.h
|