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;
|
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)
|
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)
|
void uiUninit(void)
|
||||||
|
@ -119,17 +125,13 @@ void uiQueueMain(void (*f)(void *data), void *data)
|
||||||
gdk_threads_add_idle(doqueued, q);
|
gdk_threads_add_idle(doqueued, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timer {
|
|
||||||
int (*f)(void *);
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static gboolean doTimer(gpointer data)
|
static gboolean doTimer(gpointer data)
|
||||||
{
|
{
|
||||||
struct timer *t = (struct timer *) data;
|
struct timer *t = (struct timer *) data;
|
||||||
|
|
||||||
if (!(*(t->f))(t->data)) {
|
if (!(*(t->f))(t->data)) {
|
||||||
g_hash_table_remove(timers, t);
|
g_hash_table_remove(timers, t);
|
||||||
|
g_source_remove(t->gtk_source_id);
|
||||||
uiprivFree(t);
|
uiprivFree(t);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +145,6 @@ void uiTimer(int milliseconds, int (*f)(void *data), void *data)
|
||||||
t = uiprivNew(struct timer);
|
t = uiprivNew(struct timer);
|
||||||
t->f = f;
|
t->f = f;
|
||||||
t->data = data;
|
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);
|
g_hash_table_add(timers, t);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue