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
This commit is contained in:
gdivos 2019-01-17 20:58:14 +01:00
parent d305440fa0
commit 3237d60ee8
1 changed files with 10 additions and 8 deletions

View File

@ -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);
}