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_job_from_queue_locked (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);
32 add_job_to_queue_locked (GQueue *queue,
36 g_queue_push_tail (queue, job);
37 g_cond_broadcast (render_cond);
42 notify_finished (GObject *job)
44 ev_job_finished (EV_JOB (job));
51 handle_job (EvJob *job)
53 g_object_ref (G_OBJECT (job));
55 if (EV_IS_JOB_THUMBNAIL (job))
56 ev_job_thumbnail_run (EV_JOB_THUMBNAIL (job));
57 else if (EV_IS_JOB_LINKS (job))
58 ev_job_links_run (EV_JOB_LINKS (job));
59 else if (EV_IS_JOB_RENDER (job))
60 ev_job_render_run (EV_JOB_RENDER (job));
62 /* We let the idle own a ref, as we (the queue) are done with the job. */
63 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
64 (GSourceFunc) notify_finished,
70 search_for_jobs_unlocked (void)
74 job = (EvJob *) g_queue_pop_head (render_queue_high);
78 job = (EvJob *) g_queue_pop_head (thumbnail_queue_high);
82 job = (EvJob *) g_queue_pop_head (render_queue_low);
86 job = (EvJob *) g_queue_pop_head (links_queue);
90 job = (EvJob *) g_queue_pop_head (thumbnail_queue_low);
98 no_jobs_available_unlocked (void)
100 return g_queue_is_empty (render_queue_high)
101 && g_queue_is_empty (render_queue_low)
102 && g_queue_is_empty (links_queue)
103 && g_queue_is_empty (thumbnail_queue_high)
104 && g_queue_is_empty (thumbnail_queue_low);
107 /* the thread mainloop function */
109 ev_render_thread (gpointer data)
114 g_mutex_lock (ev_queue_mutex);
115 if (no_jobs_available_unlocked ()) {
116 g_cond_wait (render_cond, ev_queue_mutex);
119 job = search_for_jobs_unlocked ();
120 g_mutex_unlock (ev_queue_mutex);
122 /* Now that we have our job, we handle it */
125 g_object_unref (G_OBJECT (job));
132 /* Public Functions */
134 ev_job_queue_init (void)
136 if (!g_thread_supported ()) g_thread_init (NULL);
138 render_cond = g_cond_new ();
139 ev_queue_mutex = g_mutex_new ();
141 links_queue = g_queue_new ();
142 render_queue_high = g_queue_new ();
143 render_queue_low = g_queue_new ();
144 thumbnail_queue_high = g_queue_new ();
145 thumbnail_queue_low = g_queue_new ();
147 g_thread_create (ev_render_thread, NULL, FALSE, NULL);
152 find_queue (EvJob *job,
153 EvJobPriority priority)
155 if (EV_IS_JOB_RENDER (job)) {
156 if (priority == EV_JOB_PRIORITY_HIGH)
157 return render_queue_high;
159 return render_queue_low;
160 } else if (EV_IS_JOB_THUMBNAIL (job)) {
161 if (priority == EV_JOB_PRIORITY_HIGH)
162 return thumbnail_queue_high;
164 return thumbnail_queue_low;
165 } else if (EV_IS_JOB_LINKS (job)) {
166 /* the priority doesn't effect links */
170 g_assert_not_reached ();
175 ev_job_queue_add_job (EvJob *job,
176 EvJobPriority priority)
180 g_return_if_fail (EV_IS_JOB (job));
182 queue = find_queue (job, priority);
184 g_mutex_lock (ev_queue_mutex);
185 add_job_to_queue_locked (queue, job);
186 g_mutex_unlock (ev_queue_mutex);
190 ev_job_queue_update_job (EvJob *job,
191 EvJobPriority new_priority)
193 gboolean retval = FALSE;
195 g_return_val_if_fail (EV_IS_JOB (job), FALSE);
197 g_mutex_lock (ev_queue_mutex);
200 if (EV_IS_JOB_THUMBNAIL (job)) {
201 if (new_priority == EV_JOB_PRIORITY_LOW) {
202 if (remove_job_from_queue_locked (thumbnail_queue_high, job)) {
203 add_job_to_queue_locked (thumbnail_queue_low, job);
206 } else if (new_priority == EV_JOB_PRIORITY_HIGH) {
207 if (remove_job_from_queue_locked (thumbnail_queue_low, job)) {
208 add_job_to_queue_locked (thumbnail_queue_high, job);
212 } else if (EV_IS_JOB_RENDER (job)) {
213 if (new_priority == EV_JOB_PRIORITY_LOW) {
214 if (remove_job_from_queue_locked (render_queue_high, job)) {
215 add_job_to_queue_locked (render_queue_low, job);
218 } else if (new_priority == EV_JOB_PRIORITY_HIGH) {
219 if (remove_job_from_queue_locked (render_queue_low, job)) {
220 add_job_to_queue_locked (render_queue_high, job);
225 /* We don't have a priority queue for any of the other jobs */
227 g_object_unref (job);
228 g_mutex_unlock (ev_queue_mutex);
234 ev_job_queue_remove_job (EvJob *job)
236 gboolean retval = FALSE;
238 g_return_val_if_fail (EV_IS_JOB (job), FALSE);
240 g_mutex_lock (ev_queue_mutex);
242 if (EV_IS_JOB_THUMBNAIL (job)) {
243 retval = remove_job_from_queue_locked (thumbnail_queue_high, job);
244 retval = retval || remove_job_from_queue_locked (thumbnail_queue_low, job);
245 } else if (EV_IS_JOB_RENDER (job)) {
246 retval = remove_job_from_queue_locked (render_queue_high, job);
247 retval = retval || remove_job_from_queue_locked (render_queue_low, job);
248 } else if (EV_IS_JOB_LINKS (job)) {
249 retval = remove_job_from_queue_locked (links_queue, job);
251 g_assert_not_reached ();
254 g_mutex_unlock (ev_queue_mutex);