1 #include "ev-job-queue.h"
3 /* Like glib calling convention, all functions with _locked in their name assume
4 * that we've already locked the doc mutex and can freely and safely access
7 GCond *render_cond = NULL;
8 GMutex *ev_queue_mutex = NULL;
10 static GQueue *links_queue = NULL;
11 static GQueue *render_queue_high = NULL;
12 static GQueue *render_queue_low = NULL;
13 static GQueue *thumbnail_queue_high = NULL;
14 static GQueue *thumbnail_queue_low = NULL;
17 remove_object_from_queue (GQueue *queue, EvJob *job)
21 list = g_queue_find (queue, job);
23 g_object_unref (G_OBJECT (job));
24 g_queue_delete_link (queue, list);
33 notify_finished (GObject *job)
35 ev_job_finished (EV_JOB (job));
42 handle_job (EvJob *job)
44 g_object_ref (G_OBJECT (job));
46 if (EV_IS_JOB_THUMBNAIL (job))
47 ev_job_thumbnail_run (EV_JOB_THUMBNAIL (job));
48 else if (EV_IS_JOB_LINKS (job))
49 ev_job_links_run (EV_JOB_LINKS (job));
50 else if (EV_IS_JOB_RENDER (job))
51 ev_job_render_run (EV_JOB_RENDER (job));
53 /* We let the idle own a ref, as we (the queue) are done with the job. */
54 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
55 (GSourceFunc) notify_finished,
61 search_for_jobs_unlocked (void)
65 job = (EvJob *) g_queue_pop_head (render_queue_high);
69 job = (EvJob *) g_queue_pop_head (thumbnail_queue_high);
73 job = (EvJob *) g_queue_pop_head (render_queue_low);
77 job = (EvJob *) g_queue_pop_head (links_queue);
81 job = (EvJob *) g_queue_pop_head (thumbnail_queue_low);
89 no_jobs_available_unlocked (void)
91 return g_queue_is_empty (render_queue_high)
92 && g_queue_is_empty (render_queue_low)
93 && g_queue_is_empty (links_queue)
94 && g_queue_is_empty (thumbnail_queue_high)
95 && g_queue_is_empty (thumbnail_queue_low);
98 /* the thread mainloop function */
100 ev_render_thread (gpointer data)
105 g_mutex_lock (ev_queue_mutex);
106 if (no_jobs_available_unlocked ()) {
107 g_cond_wait (render_cond, ev_queue_mutex);
110 job = search_for_jobs_unlocked ();
111 g_mutex_unlock (ev_queue_mutex);
113 /* Now that we have our job, we handle it */
116 g_object_unref (G_OBJECT (job));
123 /* Public Functions */
125 ev_job_queue_init (void)
127 if (!g_thread_supported ()) g_thread_init (NULL);
129 render_cond = g_cond_new ();
130 ev_queue_mutex = g_mutex_new ();
132 links_queue = g_queue_new ();
133 render_queue_high = g_queue_new ();
134 render_queue_low = g_queue_new ();
135 thumbnail_queue_high = g_queue_new ();
136 thumbnail_queue_low = g_queue_new ();
138 g_thread_create (ev_render_thread, NULL, FALSE, NULL);
143 find_queue (EvJob *job,
144 EvJobPriority priority)
146 if (EV_IS_JOB_RENDER (job)) {
147 if (priority == EV_JOB_PRIORITY_HIGH)
148 return render_queue_high;
150 return render_queue_low;
151 } else if (EV_IS_JOB_THUMBNAIL (job)) {
152 if (priority == EV_JOB_PRIORITY_HIGH)
153 return thumbnail_queue_high;
155 return thumbnail_queue_low;
156 } else if (EV_IS_JOB_LINKS (job)) {
157 /* the priority doesn't effect links */
161 g_assert_not_reached ();
166 ev_job_queue_add_job (EvJob *job,
167 EvJobPriority priority)
171 g_return_if_fail (EV_IS_JOB (job));
173 queue = find_queue (job, priority);
175 g_mutex_lock (ev_queue_mutex);
178 g_queue_push_tail (queue, job);
179 g_cond_broadcast (render_cond);
181 g_mutex_unlock (ev_queue_mutex);
186 ev_job_queue_remove_job (EvJob *job)
188 gboolean retval = FALSE;
190 g_return_val_if_fail (EV_IS_JOB (job), FALSE);
192 g_mutex_lock (ev_queue_mutex);
194 if (EV_IS_JOB_THUMBNAIL (job)) {
195 retval = remove_object_from_queue (thumbnail_queue_high, job);
196 retval = retval || remove_object_from_queue (thumbnail_queue_low, job);
197 } else if (EV_IS_JOB_RENDER (job)) {
198 retval = remove_object_from_queue (render_queue_high, job);
199 retval = retval || remove_object_from_queue (render_queue_low, job);
200 } else if (EV_IS_JOB_LINKS (job)) {
201 retval = remove_object_from_queue (links_queue, job);
203 g_assert_not_reached ();
206 g_mutex_unlock (ev_queue_mutex);