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:
parent
d305440fa0
commit
3237d60ee8
18
unix/main.c
18
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue