After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 634239 - Child GSources
Child GSources
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: mainloop
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks: 634241
 
 
Reported: 2010-11-07 19:52 UTC by Dan Winship
Modified: 2010-11-26 21:01 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gmain: move finalization of GSource outside of context lock (1.01 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review
gmain: fix some silly code in a programmer-error case (1.26 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review
Implement closure-related methods for gio GSource types (5.80 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review
Add g_source_set_dummy_callback() (3.69 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review
gmain: add g_source_add_child_source and g_source_remove_child_source (13.86 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review
GCancellable: add g_cancellable_create_source() (9.26 KB, patch)
2010-11-07 19:52 UTC, Dan Winship
committed Details | Review

Description Dan Winship 2010-11-07 19:52:03 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?
Comment 1 Dan Winship 2010-11-07 19:52:06 UTC
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
Comment 2 Dan Winship 2010-11-07 19:52:10 UTC
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.
Comment 3 Dan Winship 2010-11-07 19:52:12 UTC
Created attachment 174013 [details] [review]
Implement closure-related methods for gio GSource types

Also, fix up the argument ordering on GFDSourceFunc
Comment 4 Dan Winship 2010-11-07 19:52:15 UTC
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.
Comment 5 Dan Winship 2010-11-07 19:52:18 UTC
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.
Comment 6 Dan Winship 2010-11-07 19:52:20 UTC
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.
Comment 8 Allison Karlitskaya (desrt) 2010-11-11 20:55:25 UTC
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?
Comment 9 Dan Winship 2010-11-26 20:11:48 UTC
(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.
Comment 10 Dan Winship 2010-11-26 21:01:15 UTC
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()