[evolution/gnome-3-18] Bug 758665 - Hangs auto-saving mail with big attachments
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/gnome-3-18] Bug 758665 - Hangs auto-saving mail with big attachments
- Date: Wed, 25 Nov 2015 17:39:05 +0000 (UTC)
commit 86b512e165d561f8295e426e42ea106df753987f
Author: Milan Crha <mcrha redhat com>
Date: Wed Nov 25 18:33:43 2015 +0100
Bug 758665 - Hangs auto-saving mail with big attachments
modules/composer-autosave/e-autosave-utils.c | 72 +++++++++++++------------
1 files changed, 37 insertions(+), 35 deletions(-)
---
diff --git a/modules/composer-autosave/e-autosave-utils.c b/modules/composer-autosave/e-autosave-utils.c
index f9db63f..2e83b2a 100644
--- a/modules/composer-autosave/e-autosave-utils.c
+++ b/modules/composer-autosave/e-autosave-utils.c
@@ -183,13 +183,16 @@ load_snapshot_loaded_cb (GFile *snapshot_file,
}
static void
-save_snapshot_splice_cb (GOutputStream *output_stream,
+save_snapshot_splice_cb (CamelDataWrapper *data_wrapper,
GAsyncResult *result,
GSimpleAsyncResult *simple)
{
GError *local_error = NULL;
- g_output_stream_splice_finish (output_stream, result, &local_error);
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (g_task_is_valid (result, data_wrapper));
+
+ g_task_propagate_int (G_TASK (result), &local_error);
if (local_error != NULL)
g_simple_async_result_take_error (simple, local_error);
@@ -199,15 +202,38 @@ save_snapshot_splice_cb (GOutputStream *output_stream,
}
static void
+write_message_to_stream_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GOutputStream *output_stream;
+ gssize bytes_written;
+ GError *local_error = NULL;
+
+ output_stream = task_data;
+
+ bytes_written = camel_data_wrapper_decode_to_output_stream_sync (
+ CAMEL_DATA_WRAPPER (source_object),
+ output_stream, cancellable, &local_error);
+
+ g_output_stream_close (output_stream, cancellable, local_error ? NULL : &local_error);
+
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_int (task, bytes_written);
+ }
+}
+
+static void
save_snapshot_get_message_cb (EMsgComposer *composer,
GAsyncResult *result,
GSimpleAsyncResult *simple)
{
SaveContext *context;
CamelMimeMessage *message;
- GInputStream *input_stream;
- CamelStream *camel_stream;
- GByteArray *buffer;
+ GTask *task;
GError *local_error = NULL;
context = g_simple_async_result_get_op_res_gpointer (simple);
@@ -225,38 +251,14 @@ save_snapshot_get_message_cb (EMsgComposer *composer,
g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
- /* Decode the message to an in-memory buffer. We have to do this
- * because CamelStreams are synchronous-only, and using threads is
- * dangerous because CamelDataWrapper is not reentrant. */
- buffer = g_byte_array_new ();
- camel_stream = camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (
- CAMEL_STREAM_MEM (camel_stream), buffer);
- camel_data_wrapper_decode_to_stream_sync (
- CAMEL_DATA_WRAPPER (message), camel_stream, NULL, NULL);
- g_object_unref (camel_stream);
+ task = g_task_new (message, context->cancellable, (GAsyncReadyCallback) save_snapshot_splice_cb,
simple);
- g_object_unref (message);
+ g_task_set_task_data (task, g_object_ref (context->output_stream), g_object_unref);
- /* Load the buffer into a GMemoryInputStream. */
- input_stream = g_memory_input_stream_new ();
- if (buffer->len > 0)
- g_memory_input_stream_add_data (
- G_MEMORY_INPUT_STREAM (input_stream),
- buffer->data, (gssize) buffer->len,
- (GDestroyNotify) g_free);
- g_byte_array_free (buffer, FALSE);
-
- /* Splice the input and output streams. */
- g_output_stream_splice_async (
- context->output_stream, input_stream,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
- G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- G_PRIORITY_DEFAULT, context->cancellable,
- (GAsyncReadyCallback) save_snapshot_splice_cb,
- simple);
-
- g_object_unref (input_stream);
+ g_task_run_in_thread (task, write_message_to_stream_thread);
+
+ g_object_unref (task);
+ g_object_unref (message);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]