This is important when you operate upon your objects
from within idle handlers, but may have freed the object
before the dispatch of your idle handler.
This will fail in a multi-threaded application if the
widget is destroyed before the idle handler fires due
to the use after free in the callback. A solution, to
this particular problem, is to check to if the source
has already been destroy within the callback.
g_mutex_lock (&self->idle_id_mutex);
if (!g_source_is_destroyed (g_main_current_source ()))
{
// do stuff with self
}
g_mutex_unlock (&self->idle_id_mutex);
return FALSE;
}
]|
Calls to this function from a thread other than the one acquired by the
#GMainContext the #GSource is attached to are typically redundant, as the
source could be destroyed immediately after this function returns. However,
once a source is destroyed it cannot be un-destroyed, so this function can be
used for opportunistic checks from any thread.
Returns whether @source has been destroyed.
This is important when you operate upon your objects from within idle handlers, but may have freed the object before the dispatch of your idle handler.
|[<!-- language="C" --> static gboolean idle_callback (gpointer data) { SomeWidget *self = data;
g_mutex_lock (&self->idle_id_mutex); // do stuff with self self->idle_id = 0; g_mutex_unlock (&self->idle_id_mutex);
return G_SOURCE_REMOVE; }
static void some_widget_do_stuff_later (SomeWidget *self) { g_mutex_lock (&self->idle_id_mutex); self->idle_id = g_idle_add (idle_callback, self); g_mutex_unlock (&self->idle_id_mutex); }
static void some_widget_init (SomeWidget *self) { g_mutex_init (&self->idle_id_mutex);
// ... }
static void some_widget_finalize (GObject *object) { SomeWidget *self = SOME_WIDGET (object);
if (self->idle_id) g_source_remove (self->idle_id);
g_mutex_clear (&self->idle_id_mutex);
G_OBJECT_CLASS (parent_class)->finalize (object); } ]|
This will fail in a multi-threaded application if the widget is destroyed before the idle handler fires due to the use after free in the callback. A solution, to this particular problem, is to check to if the source has already been destroy within the callback.
|[<!-- language="C" --> static gboolean idle_callback (gpointer data) { SomeWidget *self = data;
g_mutex_lock (&self->idle_id_mutex); if (!g_source_is_destroyed (g_main_current_source ())) { // do stuff with self } g_mutex_unlock (&self->idle_id_mutex);
return FALSE; } ]|
Calls to this function from a thread other than the one acquired by the #GMainContext the #GSource is attached to are typically redundant, as the source could be destroyed immediately after this function returns. However, once a source is destroyed it cannot be un-destroyed, so this function can be used for opportunistic checks from any thread.