mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-29 18:44:55 +01:00
Fix ':close' command
Currently, zathura crashes while performing ':close' command with the following error: GThread-ERROR **: file gthread-posix.c: line 226 (g_cond_free_posix_impl): error 'Device or resource busy' during 'pthread_cond_destroy ((pthread_cond_t *) cond)' The error is because 'render' thread holds condition variable while waiting for new pages to render. This patch modifies zathura's code to correctly kill render thread and free allocated resources when the document is being closed. NOTE: should be applied on top of "Allow changing of "pages-per-row" variable at runtime" commit to avoid conflicts in the 'page_view_set_mode()' function. Signed-off-by: Pavel Borzenkov <pavel.borzenkov@gmail.com>
This commit is contained in:
parent
333cfa4df0
commit
caccb94c69
3 changed files with 34 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
13
render.c
13
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);
|
||||
}
|
||||
|
||||
|
|
29
zathura.c
29
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++)
|
||||
|
|
Loading…
Reference in a new issue