Reimplement render thread using GThreadPool

This commit is contained in:
Sebastian Ramacher 2012-03-02 17:51:48 +01:00
parent 7f6ad25e02
commit 2a0422b5e1
2 changed files with 24 additions and 114 deletions

117
render.c
View file

@ -12,42 +12,26 @@
#include "page_widget.h" #include "page_widget.h"
#include "utils.h" #include "utils.h"
void* render_job(void* data); static void render_job(void* data, void* user_data);
bool render(zathura_t* zathura, zathura_page_t* page); static bool render(zathura_t* zathura, zathura_page_t* page);
void* struct render_thread_s
render_job(void* data)
{ {
render_thread_t* render_thread = (render_thread_t*) data; GThreadPool* pool; /**< Pool of threads */
};
while (true) { static void
g_mutex_lock(render_thread->lock); render_job(void* data, void* user_data)
{
if (girara_list_size(render_thread->list) == 0) { zathura_page_t* page = data;
g_cond_wait(render_thread->cond, render_thread->lock); zathura_t* zathura = user_data;
if (page == NULL || zathura == NULL) {
return;
} }
if (girara_list_size(render_thread->list) == 0) { if (render(zathura, page) != true) {
/* girara_error("Rendering failed (page %d)\n", page->number);
* We've been signaled with g_cond_signal(), but the list
* is still empty. This means that the signal came from
* render_free() and current document is being closed.
* We should unlock the mutex and kill the thread.
*/
g_mutex_unlock(render_thread->lock);
g_thread_exit(0);
} }
zathura_page_t* page = (zathura_page_t*) girara_list_nth(render_thread->list, 0);
girara_list_remove(render_thread->list, page);
g_mutex_unlock(render_thread->lock);
if (render(render_thread->zathura, page) != true) {
girara_error("Rendering failed\n");
}
}
return NULL;
} }
render_thread_t* render_thread_t*
@ -55,31 +39,9 @@ render_init(zathura_t* zathura)
{ {
render_thread_t* render_thread = g_malloc0(sizeof(render_thread_t)); render_thread_t* render_thread = g_malloc0(sizeof(render_thread_t));
/* init */
render_thread->zathura = zathura;
/* setup */ /* setup */
render_thread->list = girara_list_new(); render_thread->pool = g_thread_pool_new(render_job, zathura, 1, TRUE, NULL);
if (render_thread->pool == NULL) {
if (!render_thread->list) {
goto error_free;
}
render_thread->cond = g_cond_new();
if (!render_thread->cond) {
goto error_free;
}
render_thread->lock = g_mutex_new();
if (!render_thread->lock) {
goto error_free;
}
render_thread->thread = g_thread_create(render_job, render_thread, TRUE, NULL);
if (!render_thread->thread) {
goto error_free; goto error_free;
} }
@ -87,46 +49,19 @@ render_init(zathura_t* zathura)
error_free: error_free:
if (render_thread->list) { render_free(render_thread);
girara_list_free(render_thread->list);
}
if (render_thread->cond) {
g_cond_free(render_thread->cond);
}
if (render_thread->lock) {
g_mutex_free(render_thread->lock);
}
g_free(render_thread);
return NULL; return NULL;
} }
void void
render_free(render_thread_t* render_thread) render_free(render_thread_t* render_thread)
{ {
if (!render_thread) { if (render_thread == NULL) {
return; return;
} }
if (render_thread->list) { if (render_thread->pool) {
girara_list_clear(render_thread->list); g_thread_pool_free(render_thread->pool, TRUE, TRUE);
}
if (render_thread->cond) {
g_cond_signal(render_thread->cond);
g_thread_join(render_thread->thread);
g_cond_free(render_thread->cond);
}
if (render_thread->list) {
girara_list_free(render_thread->list);
}
if (render_thread->lock) {
g_mutex_free(render_thread->lock);
} }
g_free(render_thread); g_free(render_thread);
@ -135,21 +70,15 @@ render_free(render_thread_t* render_thread)
bool bool
render_page(render_thread_t* render_thread, zathura_page_t* page) render_page(render_thread_t* render_thread, zathura_page_t* page)
{ {
if (!render_thread || !page || !render_thread->list) { if (render_thread == NULL || page == NULL || render_thread->pool == NULL) {
return false; return false;
} }
g_mutex_lock(render_thread->lock); g_thread_pool_push(render_thread->pool, page, NULL);
if (!girara_list_contains(render_thread->list, page)) {
girara_list_append(render_thread->list, page);
}
g_cond_signal(render_thread->cond);
g_mutex_unlock(render_thread->lock);
return true; return true;
} }
bool static bool
render(zathura_t* zathura, zathura_page_t* page) render(zathura_t* zathura, zathura_page_t* page)
{ {
if (zathura == NULL || page == NULL) { if (zathura == NULL || page == NULL) {

View file

@ -10,15 +10,6 @@
#include "zathura.h" #include "zathura.h"
#include "callbacks.h" #include "callbacks.h"
struct render_thread_s
{
girara_list_t* list; /**< The list of pages */
GThread* thread; /**< The thread object */
GMutex* lock; /**< Lock */
GCond* cond; /**< Condition */
zathura_t* zathura; /**< Zathura object */
};
/** /**
* This function initializes a render thread * This function initializes a render thread
* *
@ -53,14 +44,4 @@ bool render_page(render_thread_t* render_thread, zathura_page_t* page);
*/ */
void render_all(zathura_t* zathura); void render_all(zathura_t* zathura);
/**
* Renders page
*
* @param widget Drawing area
* @param event Event
* @param data Optional data
* @return true if no error occured
*/
gboolean page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data);
#endif // RENDER_H #endif // RENDER_H