gmain: Use atomic logic to set and use dispose function

It can be read/written in a racy way, so let's be safer.
This commit is contained in:
Marco Trevisan (Treviño) 2025-01-31 13:04:47 +01:00
parent a5bc497021
commit 42283ffb45

View File

@ -32,6 +32,7 @@
*/
#include "config.h"
#include "glib.h"
#include "glibconfig.h"
#include "glib_trace.h"
@ -978,10 +979,14 @@ void
g_source_set_dispose_function (GSource *source,
GSourceDisposeFunc dispose)
{
gboolean was_unset G_GNUC_UNUSED;
g_return_if_fail (source != NULL);
g_return_if_fail (source->priv->dispose == NULL);
g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
source->priv->dispose = dispose;
was_unset = g_atomic_pointer_compare_and_exchange (&source->priv->dispose,
NULL, dispose);
g_return_if_fail (was_unset);
}
/* Holds context's lock */
@ -2248,11 +2253,13 @@ retry_beginning:
if (old_ref == 1)
{
/* If there's a dispose function, call this first */
if (source->priv->dispose)
GSourceDisposeFunc dispose_func;
if ((dispose_func = g_atomic_pointer_get (&source->priv->dispose)))
{
if (context)
UNLOCK_CONTEXT (context);
source->priv->dispose (source);
dispose_func (source);
if (context)
LOCK_CONTEXT (context);
}