Better lock granularity in gtkhtml fetch thread (fixes NB#110127)
[modest] / src / hildon2 / modest-msg-view-window.c
index 14f6212..aa34e70 100644 (file)
@@ -2586,11 +2586,11 @@ static gboolean idle_save_mime_part_show_result (SaveMimePartInfo *info);
 static gpointer save_mime_part_to_file (SaveMimePartInfo *info);
 static void save_mime_parts_to_file_with_checks (SaveMimePartInfo *info);
 
-static void 
+static void
 save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
 {
-       
        GList *node;
+
        for (node = info->pairs; node != NULL; node = g_list_next (node)) {
                SaveMimePartPair *pair = (SaveMimePartPair *) node->data;
                g_free (pair->filename);
@@ -3079,10 +3079,14 @@ on_fetch_image_idle_refresh_view (gpointer userdata)
 
        FetchImageData *fidata = (FetchImageData *) userdata;
        g_message ("REFRESH VIEW");
+
+       gdk_threads_enter ();
        if (GTK_WIDGET_DRAWABLE (fidata->msg_view)) {
                g_message ("QUEUING DRAW");
                gtk_widget_queue_draw (fidata->msg_view);
        }
+       gdk_threads_leave ();
+
        g_object_unref (fidata->msg_view);
        g_slice_free (FetchImageData, fidata);
        return FALSE;
@@ -3096,23 +3100,51 @@ on_fetch_image_thread (gpointer userdata)
        TnyStream *cache_stream;
 
        cache = modest_runtime_get_images_cache ();
-       cache_stream = tny_stream_cache_get_stream (cache, fidata->cache_id, (TnyStreamCacheOpenStreamFetcher) fetch_image_open_stream, (gpointer) fidata->uri);
+       cache_stream = 
+               tny_stream_cache_get_stream (cache, 
+                                            fidata->cache_id, 
+                                            (TnyStreamCacheOpenStreamFetcher) fetch_image_open_stream, 
+                                            (gpointer) fidata->uri);
        g_free (fidata->cache_id);
        g_free (fidata->uri);
 
        if (cache_stream != NULL) {
-               tny_stream_write_to_stream (cache_stream, fidata->output_stream);
+               char buffer[4096];
+
+               while (G_LIKELY (!tny_stream_is_eos (cache_stream))) {
+                       gssize nb_read;
+
+                       nb_read = tny_stream_read (cache_stream, buffer, sizeof (buffer));
+                       if (G_UNLIKELY (nb_read < 0)) {
+                               break;
+                       } else if (G_LIKELY (nb_read > 0)) {
+                               gssize nb_written = 0;
+
+                               while (G_UNLIKELY (nb_written < nb_read)) {
+                                       gssize len;
+
+                                       gdk_threads_enter ();
+                                       len = tny_stream_write (fidata->output_stream, buffer + nb_written,
+                                                               nb_read - nb_written);
+                                       gdk_threads_leave ();
+                                       if (G_UNLIKELY (len < 0))
+                                               break;
+                                       nb_written += len;
+                               }
+                       }
+               }
+               gdk_threads_enter ();
                tny_stream_close (cache_stream);
                g_object_unref (cache_stream);
+               gdk_threads_leave ();
        }
 
+       gdk_threads_enter ();
        tny_stream_close (fidata->output_stream);
        g_object_unref (fidata->output_stream);
+       gdk_threads_leave ();
 
-
-       gdk_threads_enter ();
        g_idle_add (on_fetch_image_idle_refresh_view, fidata);
-       gdk_threads_leave ();
 
        return NULL;
 }