Add g_source_set_dispose_function() for setting a dispose function for GSource

This allows GSource implementors to safely clear any other references to
the GSource while the GSource is still valid, unlike when doing the same
from the finalize function.

After the dispose function has run, it is valid for the reference count
of the GSource to be > 0 again to allow the case where another thread in
the mean-time got access to the GSource reference before the dispose
function was called.

This allows fixing a thread-safety issue in the GCancellable, GstBus and
various other GSource implementations.
This commit is contained in:
Sebastian Dröge
2019-10-20 11:10:21 +03:00
parent 691485fb7c
commit 0adf5cae35
2 changed files with 78 additions and 0 deletions

View File

@@ -204,6 +204,20 @@ typedef gboolean (*GSourceFunc) (gpointer user_data);
typedef void (*GChildWatchFunc) (GPid pid,
gint status,
gpointer user_data);
/**
* GSourceDisposeFunc:
* @source: #GSource that is currently being disposed
*
* Dispose function for @source. See g_source_set_dispose_function() for
* details.
*
* Since: 2.64
*/
GLIB_AVAILABLE_TYPE_IN_2_64
typedef void (*GSourceDisposeFunc) (GSource *source);
struct _GSource
{
/*< private >*/
@@ -536,6 +550,13 @@ GMainContext *g_main_loop_get_context (GMainLoop *loop);
GLIB_AVAILABLE_IN_ALL
GSource *g_source_new (GSourceFuncs *source_funcs,
guint struct_size);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GLIB_AVAILABLE_IN_2_64
void g_source_set_dispose_function (GSource *source,
GSourceDisposeFunc dispose);
G_GNUC_END_IGNORE_DEPRECATIONS
GLIB_AVAILABLE_IN_ALL
GSource *g_source_ref (GSource *source);
GLIB_AVAILABLE_IN_ALL