mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
gdbusnamewatching: Ensure GDestroyNotify is called in correct context
The documentation for `g_bus_watch_name()` implies that the `GDestroyNotify` for the user data will be called in the current thread default `GMainContext`. Currently, it could be called in any thread, as `client_unref()` can be called in any thread. Fix that by deferring it to an idle source if `client_unref()` finalises the `Client` object in a different thread. Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
parent
323c5d7e21
commit
72f692eae4
@ -90,6 +90,13 @@ client_ref (Client *client)
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
free_user_data_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
/* The user data is actually freed by the GDestroyNotify for the idle source */
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_unref (Client *client)
|
client_unref (Client *client)
|
||||||
{
|
{
|
||||||
@ -105,9 +112,26 @@ client_unref (Client *client)
|
|||||||
}
|
}
|
||||||
g_free (client->name);
|
g_free (client->name);
|
||||||
g_free (client->name_owner);
|
g_free (client->name_owner);
|
||||||
g_main_context_unref (client->main_context);
|
|
||||||
if (client->user_data_free_func != NULL)
|
if (client->user_data_free_func != NULL)
|
||||||
|
{
|
||||||
|
/* Ensure client->user_data_free_func() is called from the right thread */
|
||||||
|
if (client->main_context != g_main_context_get_thread_default ())
|
||||||
|
{
|
||||||
|
GSource *idle_source = g_idle_source_new ();
|
||||||
|
g_source_set_callback (idle_source, free_user_data_cb,
|
||||||
|
client->user_data,
|
||||||
|
client->user_data_free_func);
|
||||||
|
g_source_set_name (idle_source, "[gio, gdbusnamewatching.c] free_user_data_cb");
|
||||||
|
g_source_attach (idle_source, client->main_context);
|
||||||
|
g_source_unref (idle_source);
|
||||||
|
}
|
||||||
|
else
|
||||||
client->user_data_free_func (client->user_data);
|
client->user_data_free_func (client->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_main_context_unref (client->main_context);
|
||||||
|
|
||||||
g_free (client);
|
g_free (client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user