GNOME Bugzilla – Bug 634239
Child GSources
Last modified: 2010-11-26 21:01:32 UTC
from the main commit: This adds "child source" support to GSource. A child source behaves basically like a GPollFD; when you add a source to a context, all of its child sources are added with the same priority; when you destroy a source, all of its child sources are destroyed; and when a child source triggers, its parent source's dispatch function is run. Use cases include: - adding a GTimeoutSource to another source to cause the source to automatically trigger after a certain timeout. - wrapping an existing source type with a new type that has a different callback signature - creating a source that triggers based on different conditions at different times. The last case is needed for TLS in particular, because of the possibility of rehandshaking, and so sometimes when trying to write application-level data to a TLS connection, you need to first write, then read, then write again, etc. In addition to the GTimeoutSource possibility mentioned above, the last patch also adds a GCancellableSource, which would let you add cancellability to a random other source. (And also adds a test case, by virtue of porting gio's internal FDSource to use GCancellableSource, so that it then gets tested via gio/tests/unix-streams.) Currently you are required to set a dummy callback on the child source; a new method g_source_set_dummy_callback() (based on g_source_set_closure()) lets you do this without actually needing a real callback. It's still a little annoying though... Originally I had the gmain just skip the dispatch methods in those cases, but this won't work with, eg, timeout sources, which reset themselves from g_timeout_dispatch(). Another possibility would be changing all the dispatch methods to just silently no-op rather than warning or crashing if the callback is NULL?
Created attachment 174011 [details] [review] gmain: move finalization of GSource outside of context lock This avoids ugly deadlock situations such as in https://bugzilla.gnome.org/show_bug.cgi?id=586432 https://bugzilla.gnome.org/show_bug.cgi?id=626702
Created attachment 174012 [details] [review] gmain: fix some silly code in a programmer-error case Previously if a source got finalized while still attached to a context, it would warn and re-ref the source. But then it just freed it anyway... So keep the warning but drop the re-ref.
Created attachment 174013 [details] [review] Implement closure-related methods for gio GSource types Also, fix up the argument ordering on GFDSourceFunc
Created attachment 174014 [details] [review] Add g_source_set_dummy_callback() Use g_source_set_closure() and g_close_set_meta_marshal() to allow setting a do-nothing callback on any source.
Created attachment 174015 [details] [review] gmain: add g_source_add_child_source and g_source_remove_child_source This adds "child source" support to GSource. A child source behaves basically like a GPollFD; when you add a source to a context, all of its child sources are added with the same priority; when you destroy a source, all of its child sources are destroyed; and when a child source triggers, its parent source's dispatch function is run. Use cases include: - adding a GTimeoutSource to another source to cause the source to automatically trigger after a certain timeout. - wrapping an existing source type with a new type that has a different callback signature - creating a source that triggers based on different conditions at different times.
Created attachment 174016 [details] [review] GCancellable: add g_cancellable_create_source() g_cancellable_create_source() returns a GSource that triggers when its corresponding GCancellable is cancelled. This can be used with g_source_add_child_source() to add cancellability to a source. Port gasynchelper's FDSource to use this rather than doing its own cancellable handling, and also fix up its callback argument order to be more normal.
Docs for the new APIs: http://people.gnome.org/~danw/tls-docs/glib/glib-The-Main-Event-Loop.html#g-source-add-child-source http://people.gnome.org/~danw/tls-docs/gobject/gobject-Closures.html#g-source-set-dummy-callback http://people.gnome.org/~danw/tls-docs/gio/GCancellable.html#g-cancellable-source-new
My take on this thing is that maybe we could get a better experience all around by passing GMainContext *in* rather than passing GSource *out*. ie: instead of giving a GSource to a user (which they can do almost nothing with aside from attaching to a mainloop anyway) then why aren't we just using callbacks (with implicit thread-default main context registration) instead?
(In reply to comment #8) > My take on this thing is that maybe we could get a better experience all around > by passing GMainContext *in* rather than passing GSource *out*. While this *MAY* end up being true for glib 4.0 (though that's not yet obvious), it would be silly to make new 2.x APIs inconsistent with existing ones.
Attachment 174011 [details] pushed as b358202 - gmain: move finalization of GSource outside of context lock Attachment 174012 [details] pushed as ece936e - gmain: fix some silly code in a programmer-error case Attachment 174013 [details] pushed as 73d823a - Implement closure-related methods for gio GSource types Attachment 174014 [details] pushed as e910205 - Add g_source_set_dummy_callback() Attachment 174015 [details] pushed as d15cdbe - gmain: add g_source_add_child_source and g_source_remove_child_source Attachment 174016 [details] pushed as 6181c7d - GCancellable: add g_cancellable_create_source()