Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2008-08-22 09:59:16 (GMT)
committer Carlos Garcia Campos <carlosgc@src.gnome.org>2008-08-22 09:59:16 (GMT)
commit27dce4e648c04fc784527610af77c30cf1318111 (patch)
tree184ed8835fab88c7bfbc1a7bd4263f3e9fc3d993 /shell
parent614124da1fe2cff8e085faad88320d0dcf4269ad (diff)
Add a new job to get the attachments in a thread with the document lock
2008-08-22 Carlos Garcia Campos <carlosgc@gnome.org> * shell/ev-jobs.[ch]: (ev_job_attachments_init), (ev_job_attachments_dispose), (ev_job_attachments_run), (ev_job_attachments_class_init), (ev_job_attachments_new): * shell/ev-sidebar-attachments.c: (ev_sidebar_attachments_set_document): Add a new job to get the attachments in a thread with the document lock held. Fixes bug #548653. svn path=/trunk/; revision=3116
Diffstat (limited to 'shell')
-rw-r--r--shell/ev-jobs.c96
-rw-r--r--shell/ev-jobs.h24
-rw-r--r--shell/ev-sidebar-attachments.c64
3 files changed, 145 insertions, 39 deletions
diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c
index dd8fb09..fb967cc 100644
--- a/shell/ev-jobs.c
+++ b/shell/ev-jobs.c
@@ -38,20 +38,22 @@
#include <glib/gi18n.h>
#include <unistd.h>
-static void ev_job_init (EvJob *job);
-static void ev_job_class_init (EvJobClass *class);
-static void ev_job_links_init (EvJobLinks *job);
-static void ev_job_links_class_init (EvJobLinksClass *class);
-static void ev_job_render_init (EvJobRender *job);
-static void ev_job_render_class_init (EvJobRenderClass *class);
-static void ev_job_thumbnail_init (EvJobThumbnail *job);
-static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
-static void ev_job_load_init (EvJobLoad *job);
-static void ev_job_load_class_init (EvJobLoadClass *class);
-static void ev_job_save_init (EvJobSave *job);
-static void ev_job_save_class_init (EvJobSaveClass *class);
-static void ev_job_print_init (EvJobPrint *job);
-static void ev_job_print_class_init (EvJobPrintClass *class);
+static void ev_job_init (EvJob *job);
+static void ev_job_class_init (EvJobClass *class);
+static void ev_job_links_init (EvJobLinks *job);
+static void ev_job_links_class_init (EvJobLinksClass *class);
+static void ev_job_attachments_init (EvJobAttachments *job);
+static void ev_job_attachments_class_init (EvJobAttachmentsClass *class);
+static void ev_job_render_init (EvJobRender *job);
+static void ev_job_render_class_init (EvJobRenderClass *class);
+static void ev_job_thumbnail_init (EvJobThumbnail *job);
+static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
+static void ev_job_load_init (EvJobLoad *job);
+static void ev_job_load_class_init (EvJobLoadClass *class);
+static void ev_job_save_init (EvJobSave *job);
+static void ev_job_save_class_init (EvJobSaveClass *class);
+static void ev_job_print_init (EvJobPrint *job);
+static void ev_job_print_class_init (EvJobPrintClass *class);
enum {
CANCELLED,
@@ -75,6 +77,7 @@ static guint job_fonts_signals[FONTS_LAST_SIGNAL] = { 0 };
G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobAttachments, ev_job_attachments, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
@@ -348,6 +351,71 @@ ev_job_links_new (EvDocument *document)
return job;
}
+/* EvJobAttachments */
+static void
+ev_job_attachments_init (EvJobAttachments *job)
+{
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_attachments_dispose (GObject *object)
+{
+ EvJobAttachments *job;
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ job = EV_JOB_ATTACHMENTS (object);
+
+ if (job->attachments) {
+ g_list_foreach (job->attachments, (GFunc)g_object_unref, NULL);
+ g_list_free (job->attachments);
+ job->attachments = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_job_attachments_parent_class)->dispose) (object);
+}
+
+static gboolean
+ev_job_attachments_run (EvJob *job)
+{
+ EvJobAttachments *job_attachments = EV_JOB_ATTACHMENTS (job);
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_doc_mutex_lock ();
+ job_attachments->attachments = ev_document_get_attachments (job->document);
+ ev_document_doc_mutex_unlock ();
+
+ ev_job_succeeded (job);
+
+ return FALSE;
+}
+
+static void
+ev_job_attachments_class_init (EvJobAttachmentsClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_attachments_dispose;
+ job_class->run = ev_job_attachments_run;
+}
+
+EvJob *
+ev_job_attachments_new (EvDocument *document)
+{
+ EvJob *job;
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ job = g_object_new (EV_TYPE_JOB_ATTACHMENTS, NULL);
+ job->document = g_object_ref (document);
+
+ return job;
+}
+
/* EvJobRender */
static void
ev_job_render_init (EvJobRender *job)
diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h
index 95c7f7d..e89f646 100644
--- a/shell/ev-jobs.h
+++ b/shell/ev-jobs.h
@@ -42,6 +42,9 @@ typedef struct _EvJobThumbnailClass EvJobThumbnailClass;
typedef struct _EvJobLinks EvJobLinks;
typedef struct _EvJobLinksClass EvJobLinksClass;
+typedef struct _EvJobAttachments EvJobAttachments;
+typedef struct _EvJobAttachmentsClass EvJobAttachmentsClass;
+
typedef struct _EvJobFonts EvJobFonts;
typedef struct _EvJobFontsClass EvJobFontsClass;
@@ -65,6 +68,11 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
#define EV_JOB_LINKS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LINKS, EvJobLinksClass))
#define EV_IS_JOB_LINKS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LINKS))
+#define EV_TYPE_JOB_ATTACHMENTS (ev_job_attachments_get_type())
+#define EV_JOB_ATTACHMENTS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_ATTACHMENTS, EvJobAttachments))
+#define EV_JOB_ATTACHMENTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_ATTACHMENTS, EvJobAttachmentsClass))
+#define EV_IS_JOB_ATTACHMENTS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_ATTACHMENTS))
+
#define EV_TYPE_JOB_RENDER (ev_job_render_get_type())
#define EV_JOB_RENDER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_RENDER, EvJobRender))
#define EV_JOB_RENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_RENDER, EvJobRenderClass))
@@ -142,6 +150,18 @@ struct _EvJobLinksClass
EvJobClass parent_class;
};
+struct _EvJobAttachments
+{
+ EvJob parent;
+
+ GList *attachments;
+};
+
+struct _EvJobAttachmentsClass
+{
+ EvJobClass parent_class;
+};
+
typedef enum {
EV_RENDER_INCLUDE_NONE = 0,
EV_RENDER_INCLUDE_LINKS = 1 << 0,
@@ -292,6 +312,10 @@ void ev_job_set_run_mode (EvJob *job,
GType ev_job_links_get_type (void) G_GNUC_CONST;
EvJob *ev_job_links_new (EvDocument *document);
+/* EvJobAttachments */
+GType ev_job_attachments_get_type (void) G_GNUC_CONST;
+EvJob *ev_job_attachments_new (EvDocument *document);
+
/* EvJobRender */
GType ev_job_render_get_type (void) G_GNUC_CONST;
EvJob *ev_job_render_new (EvDocument *document,
diff --git a/shell/ev-sidebar-attachments.c b/shell/ev-sidebar-attachments.c
index 1b2be06..fa64fbc 100644
--- a/shell/ev-sidebar-attachments.c
+++ b/shell/ev-sidebar-attachments.c
@@ -31,6 +31,8 @@
#include <glib/gstdio.h>
#include <gtk/gtk.h>
+#include "ev-jobs.h"
+#include "ev-job-scheduler.h"
#include "ev-file-helpers.h"
#include "ev-sidebar-attachments.h"
#include "ev-sidebar-page.h"
@@ -613,32 +615,12 @@ ev_sidebar_attachments_new (void)
}
static void
-ev_sidebar_attachments_set_document (EvSidebarPage *page,
- EvDocument *document)
+job_finished_callback (EvJobAttachments *job,
+ EvSidebarAttachments *ev_attachbar)
{
- EvSidebarAttachments *ev_attachbar = EV_SIDEBAR_ATTACHMENTS (page);
- GList *attachments = NULL;
GList *l;
- if (!ev_document_has_attachments (document))
- return;
-
- if (!ev_attachbar->priv->icon_theme) {
- GdkScreen *screen;
-
- screen = gtk_widget_get_screen (GTK_WIDGET (ev_attachbar));
- ev_attachbar->priv->icon_theme = gtk_icon_theme_get_for_screen (screen);
- g_signal_connect_swapped (G_OBJECT (ev_attachbar->priv->icon_theme),
- "changed",
- G_CALLBACK (ev_sidebar_attachments_update_icons),
- (gpointer) ev_attachbar);
- }
-
- attachments = ev_document_get_attachments (document);
-
- gtk_list_store_clear (ev_attachbar->priv->model);
-
- for (l = attachments; l && l->data; l = g_list_next (l)) {
+ for (l = job->attachments; l && l->data; l = g_list_next (l)) {
EvAttachment *attachment;
GtkTreeIter iter;
GdkPixbuf *pixbuf = NULL;
@@ -656,11 +638,43 @@ ev_sidebar_attachments_set_document (EvSidebarPage *page,
COLUMN_ICON, pixbuf,
COLUMN_ATTACHMENT, attachment,
-1);
+ }
- g_object_unref (attachment);
+ g_object_unref (job);
+}
+
+static void
+ev_sidebar_attachments_set_document (EvSidebarPage *page,
+ EvDocument *document)
+{
+ EvSidebarAttachments *ev_attachbar = EV_SIDEBAR_ATTACHMENTS (page);
+ EvJob *job;
+
+ if (!ev_document_has_attachments (document))
+ return;
+
+ if (!ev_attachbar->priv->icon_theme) {
+ GdkScreen *screen;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (ev_attachbar));
+ ev_attachbar->priv->icon_theme = gtk_icon_theme_get_for_screen (screen);
+ g_signal_connect_swapped (G_OBJECT (ev_attachbar->priv->icon_theme),
+ "changed",
+ G_CALLBACK (ev_sidebar_attachments_update_icons),
+ (gpointer) ev_attachbar);
}
+
+ gtk_list_store_clear (ev_attachbar->priv->model);
- g_list_free (attachments);
+ job = ev_job_attachments_new (document);
+ g_signal_connect (job, "finished",
+ G_CALLBACK (job_finished_callback),
+ ev_attachbar);
+ g_signal_connect (job, "cancelled",
+ G_CALLBACK (g_object_unref),
+ NULL);
+ /* The priority doesn't matter for this job */
+ ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
}
static gboolean