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 517137 - Need async operations with a non-default main context
Need async operations with a non-default main context
Status: RESOLVED DUPLICATE of bug 579984
Product: glib
Classification: Platform
Component: gio
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: Alexander Larsson
gtkdev
Depends on:
Blocks: 510417
 
 
Reported: 2008-02-18 05:20 UTC by Sebastian Dröge (slomo)
Modified: 2009-06-19 21:24 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Sebastian Dröge (slomo) 2008-02-18 05:20:00 UTC
Hi,
GIO currently needs a main loop running for the default main context for every async operation as the callbacks at least are made from this main context.

It would be nice if there was a _async_with_context() function for every async function that allows one to choose a non-default main context for this.

Another possibility would be async functions that simply call the callbacks from another thread instead of relying on a main loop in some main context.

This would also solve bug #517071, the reasons why such async operations are needed are listed in that bug too ;)
Comment 1 Allison Karlitskaya (desrt) 2008-02-18 06:33:42 UTC
This is also extremely important for file monitors.

Dispatching an event in another main context and/or in a dedicated thread (which could be running its own mainloop or simply looping directly) would be nice features.
Comment 2 Alexander Larsson 2008-02-18 10:24:36 UTC
I think having a main context argument in all operations, or duplicating each operation so that that is possible is a bad idea. I initially had this, but it severely bloats the API in *all* callers, for something that is extremely rare in use.

I think a better idea would be some way to set the default main context to use for the current thread and then use that.

Its a chunk of work getting all the async implementations to handle multiple main context though. The original code that did this severely complicated the dbus handling in gvfs for instance.
Comment 3 Sebastian Dröge (slomo) 2008-02-18 10:31:12 UTC
Only setting the default main context for the current thread is not enough in some cases but could work with some additional effort I guess.
Comment 4 Alexander Larsson 2008-02-18 12:07:27 UTC
I don't see how that could not be enough, as you can easily create the _async_with_context() wrapper for any async operation by setting the current threads main context, calling the normal async op, then resetting it.

Can you describe what you're unable to do with this kind of solution?
Comment 5 Allison Karlitskaya (desrt) 2008-02-18 20:27:22 UTC
As long as the set_default_context() thing was GIO-specific I agree with it for exactly the use you describe above -- using it to temporarily override the main context used by user-facing GIO API.

We were talking on IRC about all the problems that would be caused if you were able to override the default context used by glib... Consider how many libraries do things like naïvely scheduling idle handlers as a way to get code back to the mainloop.  These libraries would explode if suddenly the idle handlers started running in a different context.

I guess, by the way, that the best way to do this would be as a sort of per-thread stack.  That way you can write little wrappers like this:

gio_do_stuff_with_context (gctx *ctx)
{
  gio_push_default_context (ctx);
  gio_do_stuff();
  gio_pop_default_context ();
}

That way, regardless of what context overrides you have at entry to this function, you know that you don't get strange side-effects.
Comment 6 Behdad Esfahbod 2008-02-18 20:34:28 UTC
(In reply to comment #5)

> I guess, by the way, that the best way to do this would be as a sort of
> per-thread stack.  That way you can write little wrappers like this:
> 
> gio_do_stuff_with_context (gctx *ctx)
> {
>   gio_push_default_context (ctx);
>   gio_do_stuff();
>   gio_pop_default_context ();
> }

Since this is happening in a single function, no need for a separate stack:

gio_do_stuff_with_context (gctx *ctx)
{
  gctx *old_ctx = gio_get_default_context ();

  gio_set_default_context (ctx);
  gio_do_stuff();
  gio_set_default_context (old_ctx);
}
Comment 7 Allison Karlitskaya (desrt) 2008-02-18 21:04:12 UTC
ah... yes.  we already have a stack.  let's use it.

good call :)
Comment 8 Sebastian Dröge (slomo) 2008-02-19 11:15:19 UTC
There might be cases where it's not a single function though... and having the push/pop mechanism isn't too hard either.

If we have that I guess everything is possible ;)
Comment 9 Tim-Philipp Müller 2009-03-11 12:22:26 UTC
Has anyone started working on this yet? (e.g. as part of gnio maybe?)

Any chance of getting this into GLib 2.20?
Comment 10 Matthias Clasen 2009-03-11 15:48:09 UTC
No and no.
Comment 11 Allison Karlitskaya (desrt) 2009-03-17 16:54:17 UTC
Summary from IRC discussion about this today:

  * will add some trivial functions to gio to manipulate the context stack

  * base glib functions like g_idle_ and g_timeout_ will not be affected

  * certain interfaces/classes will be advertised as "supporting alternate main
    contexts" by way of the new functions (ie: GInputStream, GOutputStream, etc)

  * these classes/interfaces will have a new field added to their iface/vtable

  * this new field will be set non-NULL by an implementation to indicate that it
    supports alternate main contexts

  * the interface code (ie: g_input_stream_read_async) will check the vtable to
    ensure that the value is non-NULL if a non-default main context was set by
    the caller.  a g_critical will be thrown in the case that the user set a
    alternate context and the implementation is not marked as being able to
    support that.


patches forthcoming
Comment 12 Alexander Larsson 2009-03-18 11:19:32 UTC
I don't think throwing a g_critical is the right approach, as exactly what i/o implementation gets used could often be a runtime issue. I'd rather it just return an error. (possibly logging something with e.g. g_warning)
Comment 13 Dan Winship 2009-06-19 21:24:28 UTC

*** This bug has been marked as a duplicate of 579984 ***