diff --git a/document.c b/document.c index 761113a..55cdef9 100644 --- a/document.c +++ b/document.c @@ -305,6 +305,7 @@ zathura_document_free(zathura_document_t* document) for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { zathura_page_free(document->pages[page_id]); + document->pages[page_id] = NULL; } free(document->pages); @@ -427,6 +428,8 @@ zathura_page_free(zathura_page_t* page) return false; } + g_static_mutex_free(&(page->lock)); + return page->document->functions.page_free(page); } diff --git a/render.c b/render.c index 16c129a..16c0a4c 100644 --- a/render.c +++ b/render.c @@ -17,6 +17,17 @@ render_job(void* data) g_cond_wait(render_thread->cond, render_thread->lock); } + if (girara_list_size(render_thread->list) <= 0) { + /* + * 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); @@ -104,6 +115,8 @@ render_free(render_thread_t* render_thread) } if (render_thread->cond) { + g_cond_signal(render_thread->cond); + g_thread_join(render_thread->thread); g_cond_free(render_thread->cond); } diff --git a/zathura.c b/zathura.c index 5b0bf1a..dba3d87 100644 --- a/zathura.c +++ b/zathura.c @@ -308,6 +308,16 @@ error_out: return false; } +static void +remove_page_from_table(GtkWidget* page, gpointer permanent) +{ + if (!permanent) { + g_object_ref(G_OBJECT(page)); + } + + gtk_container_remove(GTK_CONTAINER(page->parent), page); +} + bool document_close(zathura_t* zathura) { @@ -315,11 +325,15 @@ document_close(zathura_t* zathura) return false; } - if (zathura->sync.render_thread) { - render_free(zathura->sync.render_thread); - } + render_free(zathura->sync.render_thread); + zathura->sync.render_thread = NULL; + + gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_view), remove_page_from_table, (gpointer)1); zathura_document_free(zathura->document); + zathura->document = NULL; + + gtk_widget_hide_all(zathura->ui.page_view); return true; } @@ -378,8 +392,6 @@ statusbar_page_number_update(zathura_t* zathura) void page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row) { - GList* child; - /* show at least one page */ if (pages_per_row == 0) { pages_per_row = 1; @@ -389,12 +401,7 @@ page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row) return; } - child = gtk_container_get_children(GTK_CONTAINER(zathura->ui.page_view)); - while (child) { - g_object_ref(G_OBJECT(child->data)); - gtk_container_remove(GTK_CONTAINER(zathura->ui.page_view), GTK_WIDGET(child->data)); - child = g_list_next(child); - } + gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_view), remove_page_from_table, (gpointer)0); gtk_table_resize(GTK_TABLE(zathura->ui.page_view), zathura->document->number_of_pages / pages_per_row + 1, pages_per_row); for (unsigned int i = 0; i < zathura->document->number_of_pages; i++)