From 3237d60ee8878d6c6aedff401c7521d0e06b7233 Mon Sep 17 00:00:00 2001 From: gdivos Date: Thu, 17 Jan 2019 20:58:14 +0100 Subject: [PATCH] Remove GTK timer source ID from main context on uninit Restarting the main loop without removing the timer source results in null-pointer dereference error in GTK. https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#mainloop-memory-management --- unix/main.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/unix/main.c b/unix/main.c index 5d349d32..a4ad3514 100644 --- a/unix/main.c +++ b/unix/main.c @@ -22,11 +22,17 @@ const char *uiInit(uiInitOptions *o) return NULL; } -struct timer; // TODO get rid of forward declaration +struct timer { + int (*f)(void *); + void *data; + guint gtk_source_id; +}; static void uninitTimer(gpointer key, gpointer value, gpointer data) { - uiprivFree((struct timer *) key); + struct timer *t = (struct timer *) key; + g_source_remove(t->gtk_source_id); + uiprivFree(t); } void uiUninit(void) @@ -119,17 +125,13 @@ void uiQueueMain(void (*f)(void *data), void *data) gdk_threads_add_idle(doqueued, q); } -struct timer { - int (*f)(void *); - void *data; -}; - static gboolean doTimer(gpointer data) { struct timer *t = (struct timer *) data; if (!(*(t->f))(t->data)) { g_hash_table_remove(timers, t); + g_source_remove(t->gtk_source_id); uiprivFree(t); return FALSE; } @@ -143,6 +145,6 @@ void uiTimer(int milliseconds, int (*f)(void *data), void *data) t = uiprivNew(struct timer); t->f = f; t->data = data; - g_timeout_add(milliseconds, doTimer, t); + t->gtk_source_id = g_timeout_add(milliseconds, doTimer, t); g_hash_table_add(timers, t); }