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 787312 - Sync methods don't block, and async methods don't invoke callbacks in the thread-default GMainContext
Sync methods don't block, and async methods don't invoke callbacks in the thr...
Status: RESOLVED OBSOLETE
Product: grilo
Classification: Other
Component: core
unspecified
Other All
: Normal normal
: ---
Assigned To: grilo-maint
grilo-maint
Depends on:
Blocks:
 
 
Reported: 2017-09-05 14:30 UTC by Debarshi Ray
Modified: 2018-09-24 09:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case: sync variants get stuck in threads (3.23 KB, text/plain)
2017-09-05 14:31 UTC, Debarshi Ray
  Details
source: Invoke the user's callback in the thread-default GMainContext (3.65 KB, patch)
2017-09-05 15:01 UTC, Debarshi Ray
none Details | Review
source: Stop random GSources from being triggered during a sync call (2.84 KB, patch)
2017-09-05 15:19 UTC, Debarshi Ray
none Details | Review
source: Stop random GSources from being triggered during a sync call (3.14 KB, patch)
2017-09-05 15:21 UTC, Debarshi Ray
none Details | Review

Description Debarshi Ray 2017-09-05 14:30:04 UTC
Forked from "Synchronous methods get stuck when used in threaded paths":
  https://bugzilla.gnome.org/show_bug.cgi?id=762496#c1

The use-case for the original complaint was:

A GMainLoop-based program that uses asynchronous operations to avoid blocking the main thread. Some of these asynchronous operations are offered by base classes or interfaces, where the implementation comes from a child or implementation class. It is a common pattern to let the base class / interface deal with all the async boilerplate, and have the child / implementation only provide a "simple" synchronous method which is run in a thread.

See the attached test case.

However, this is a sympton of a more generic problem. Let's take grl_source_resolve as an example.

The asynchronous variant uses g_idle_add* to dispatch the callbacks. ie. the callback is run in the NULL or global GMainContext. Instead, the GIO idiom is to use the thread-default GMainContext at the time of invoking the async method. Both GTask and GSimpleAsyncResult use g_main_context_ref_thread_default to track the thread-default context at the time of their construction, and use it to invoke callbacks.

This is important because sometimes the synchronous variant of a method is implemented in terms of its asynchronous counterpart by wrapping it in a new thread-default GMainContext. (This sync method might then be used by an application in a worker thread.) All the child async methods in the chain should invoke their callbacks in the thread-default GMainContext. Otherwise, even though the chain was initiated in a thread, they would be invoking their callbacks, and the remainder of the chain, in the global GMainContext, which usually means the main thread.

The synchronous variant, grl_source_resolve_sync, is almost like the one in the previous paragraph. Except it doesn't push a fresh new GMainContext before calling its asynchronous counterpart. This means that it is iterating a GMainContext with GSources that are not related to this call, and potentially triggering them. Hence, the sync call isn't really blocking because random unrelated callbacks maybe be invoked while it is running.
Comment 1 Debarshi Ray 2017-09-05 14:31:01 UTC
Created attachment 359187 [details]
Test case: sync variants get stuck in threads
Comment 2 Debarshi Ray 2017-09-05 15:01:18 UTC
Created attachment 359197 [details] [review]
source: Invoke the user's callback in the thread-default GMainContext

Here's a proof-of-concept of how I'd change the asynchronous methods.

Only compile tested. I haven't actually used it to do anything.
Comment 3 Debarshi Ray 2017-09-05 15:19:38 UTC
Created attachment 359200 [details] [review]
source: Stop random GSources from being triggered during a sync call

Similarly untested patch, but for the synchronous variant.
Comment 4 Debarshi Ray 2017-09-05 15:21:00 UTC
Created attachment 359201 [details] [review]
source: Stop random GSources from being triggered during a sync call

Sorry, forgot to 'git add' one file.
Comment 5 GNOME Infrastructure Team 2018-09-24 09:55:08 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/grilo/issues/122.