+ * g_source_add_child_source:
+ * @source:a #GSource
+ * @child_source: a second #GSource that @source should "poll"
+ *
+ * Adds @child_source to @source as a "polled" source; when @source is
+ * added to a #GMainContext, @child_source will be automatically added
+ * with the same priority, when @child_source is triggered, it will
+ * cause @source to dispatch (in addition to calling its own
+ * callback), and when @source is destroyed, it will destroy
+ * @child_source as well. (@source will also still be dispatched if
+ * its own prepare/check functions indicate that it is ready.)
+ *
+ * If you don't need @child_source to do anything on its own when it
+ * triggers, you can call g_source_set_dummy_callback() on it to set a
+ * callback that does nothing (except return %TRUE if appropriate).
+ *
+ * @source will hold a reference on @child_source while @child_source
+ * is attached to it.
+ *
+ * Since: 2.28
+ **/
+void
+g_source_add_child_source (GSource *source,
+ GSource *child_source)
+{
+ GMainContext *context;
+
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (child_source != NULL);
+ g_return_if_fail (!SOURCE_DESTROYED (source));
+ g_return_if_fail (!SOURCE_DESTROYED (child_source));
+ g_return_if_fail (child_source->context == NULL);
+ g_return_if_fail (child_source->priv == NULL || child_source->priv->parent_source == NULL);
+
+ context = source->context;
+
+ if (context)
+ LOCK_CONTEXT (context);
+
+ if (!source->priv)
+ source->priv = g_slice_new0 (GSourcePrivate);
+ if (!child_source->priv)
+ child_source->priv = g_slice_new0 (GSourcePrivate);
+
+ source->priv->child_sources = g_slist_prepend (source->priv->child_sources,
+ g_source_ref (child_source));
+ child_source->priv->parent_source = source;
+ g_source_set_priority_unlocked (child_source, context, source->priority);
+
+ if (context)
+ {
+ UNLOCK_CONTEXT (context);
+ g_source_attach (child_source, context);
+ }
+}
+
+/**
+ * g_source_remove_child_source:
+ * @source:a #GSource
+ * @child_source: a #GSource previously passed to
+ * g_source_add_child_source().
+ *
+ * Detaches @child_source from @source and destroys it.
+ *
+ * Since: 2.28
+ **/
+void
+g_source_remove_child_source (GSource *source,
+ GSource *child_source)
+{
+ GMainContext *context;
+
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (child_source != NULL);
+ g_return_if_fail (child_source->priv != NULL && child_source->priv->parent_source == source);
+ g_return_if_fail (!SOURCE_DESTROYED (source));
+ g_return_if_fail (!SOURCE_DESTROYED (child_source));
+
+ context = source->context;
+
+ if (context)
+ LOCK_CONTEXT (context);
+
+ source->priv->child_sources = g_slist_remove (source->priv->child_sources, child_source);
+ g_source_destroy_internal (child_source, context, TRUE);
+ g_source_unref_internal (child_source, context, TRUE);
+
+ if (context)
+ UNLOCK_CONTEXT (context);
+}
+
+/**