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 780296 - xdg-open/gnome-open doesn't work if service isn't started
xdg-open/gnome-open doesn't work if service isn't started
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: gio
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
: 746534 782429 (view as bug list)
Depends on: 793831
Blocks:
 
 
Reported: 2017-03-20 10:19 UTC by Pierre Ossman
Modified: 2018-05-24 19:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gio: Add hack to close up dbus-daemon race (3.97 KB, patch)
2017-05-10 11:59 UTC, Ondrej Holy
none Details | Review
gio: Add hack to close up dbus-daemon race (3.97 KB, patch)
2017-10-05 14:15 UTC, Ondrej Holy
committed Details | Review
Fix building gio-tool-open.c on Windows/Cocoa (1.70 KB, patch)
2017-10-07 02:48 UTC, Fan, Chun-wei
committed Details | Review
gdesktopappinfo: Use sync dbus calls to avoid dropping messages (3.51 KB, patch)
2018-02-27 10:39 UTC, Ondrej Holy
none Details | Review
Revert "gio: Fix gio-tool-open.c on Windows/Cocoa" (1.56 KB, patch)
2018-02-27 10:40 UTC, Ondrej Holy
none Details | Review
Revert "gio: Add hack to close up dbus-daemon race" (3.71 KB, patch)
2018-02-27 10:41 UTC, Ondrej Holy
none Details | Review

Description Pierre Ossman 2017-03-20 10:19:59 UTC
So xdg-open and gnome-open doesn't work properly with nautilus. I.e. this gives you no apparent effect:

$ xdg-open .

However running the command again works. It turns out that the first invocation starts up the nautilus service, but fails to tell it to actually open the folder. But the second attempt works fine as the service is already running.

Fedora 25 in X11 mode.

nautilus-3.22.3-1.fc25.x86_64
Comment 1 Ondrej Holy 2017-03-20 11:25:35 UTC
This is a bug in GLib. Bug 746534 resolved this for gvfs-open using an ugly workaround. However, xdg-open uses "gio open" instead of gvfs-open currently and "gio open" doesn't contain the ugly workaround unfortunately...

I can prepare this workaround also for "gio open" if maintainers wish it, but I doubt about it...

Just a note that the Bug 746534 contains also nicer solution for gdesktopappinfo, however, glib maintainers didn't want it because they thought that the bug is in dbus and dbus maintainers vice versa if I recall correctly.
Comment 2 Matthias Clasen 2017-03-26 08:51:15 UTC
(In reply to Ondrej Holy from comment #1)
> This is a bug in GLib. 

I'm tempted to close it NOTABUG. It is just the way things are.

Using shell scripts as glue layer was, is and will always be a horrible idea. I don't think you get to blame GLib for the fallout.
Comment 3 Pierre Ossman 2017-03-27 10:32:27 UTC
In that case gnome-open and xdg-open should really be removed. You can't realistically have commands that don't actually work.
Comment 4 Ondrej Holy 2017-03-27 15:14:33 UTC
Matthias, "gio open" doesn't work itself, it is not about shell scripts as far as I know...

Try the following:
1/ pkill nautilus
2/ gio open . # nothing happens, but nautilus (or any other app) should be shown
3/ gio open . # nautilus is finally opened, but on the second try

This is a problem for all dbus-activated apps. Ok, it might be a bug in D-Bus (not GLib), but I am afraid of you can't blame the shell scripts here...
Comment 5 Matthias Clasen 2017-03-30 15:44:49 UTC
it is a problem with the multi-roundtrip nature of the initial dbus handshake. Fixing this would require a flush of the connection to wait at least until the initial handshake is done, which is not easy and arguably too much effort for a corner case
Comment 6 Mark Blakeney 2017-05-09 22:31:50 UTC
A new formal release of xdg-utils was created 2 days ago at https://portland.freedesktop.org/download/. It contains xdg-open fixed to call gio open now instead of gvfs-open because gvfs-open has been depreciated since GNOME 3.24 and does not work anymore (see https://bugs.freedesktop.org/show_bug.cgi?id=100862). This new release has updated on stock Arch Linux and likely soon to many other distros. However, due to the bug discussed here (and at bug 746534), gio open does not work with Nautilus due to the same frustrating bug gvfs-open exhibited for 1 year between GNOME 3.14 to GNOME 3.17.3. Surely it is better to apply the same fix/workaround/whatever to gio open rather than leave it broken?
Comment 7 Ondrej Holy 2017-05-10 11:34:24 UTC
*** Bug 782429 has been marked as a duplicate of this bug. ***
Comment 8 Ondrej Holy 2017-05-10 11:59:00 UTC
Created attachment 351539 [details] [review]
gio: Add hack to close up dbus-daemon race

If gio open exits before the program it starts fully activates, then
the dbus-daemon may avoid doing the activating method call.

This commit works around the problem by pinging the activated application,
and waiting for a reply.

Same workaround is used in gtk-launch and was used in gvfs-open before
it was replaced by gio open.
Comment 9 Ondrej Holy 2017-05-10 12:26:12 UTC
*** Bug 746534 has been marked as a duplicate of this bug. ***
Comment 10 Simon McVittie 2017-09-28 17:32:53 UTC
Review of attachment 351539 [details] [review]:

::: gio/gio-tool-open.c
@@ +156,3 @@
 
+      /* FIXME: This chunk of madness is a workaround for a dbus-daemon bug.
+       * See https://bugzilla.gnome.org/show_bug.cgi?id=780296

If you believe this to be a dbus-daemon bug, please report it on dbus' bug tracking system.
Comment 11 Simon McVittie 2017-09-28 17:38:34 UTC
(In reply to Ondrej Holy from comment #8)
> If gio open exits before the program it starts fully activates, then
> the dbus-daemon may avoid doing the activating method call.

I think the problem here may be that if gio-open exits immediately and dbus-daemon sees that its connection has closed, then the dbus-daemon will clean up the internal state that was associated with that connection, including pending calls.

This is a general problem with GDesktopAppInfo's D-Bus-activating code path, not just gio-open (although gio-open has it worse than most, because it does exit immediately).
Comment 12 Simon McVittie 2017-09-28 17:50:03 UTC
Actually, dbus-daemon can't completely fix this - there is a race condition in which the dbus-daemon might never have even seen the activating message. The main thread submits a request to send a message to the GDBus worker thread, but doesn't guarantee to have waited for the worker thread to push that message out on the socket that is connected to the dbus-daemon. If you're really unlucky, gio-open (or any other GDesktopAppInfo user that exits shortly after triggering D-Bus activation) could exit with the message only half sent.

I don't think there is a solution for that, other than using g_app_info_launch_default_for_uri_async() and giving that method the ability to wait for D-Bus activation. That would fix the presumably more common case (message gets sent to the dbus-daemon, but by the time the activated program starts, gio-open has exited, so dbus-daemon has cancelled the pending call or something) as a side-effect.
Comment 13 Philip Withnall 2017-10-05 11:35:23 UTC
Review of attachment 351539 [details] [review]:

This looks pretty tenuous, but if it actually works as a workaround, then let’s push it to master with fixes for these two review comments; and then work on fixing the issue properly.

::: gio/gio-tool-open.c
@@ +32,3 @@
 
+static gboolean
+get_bus_name_and_path_from_uri (char *uri,

`const char *uri`

@@ +61,3 @@
+  if (app_info == NULL || !G_IS_DESKTOP_APP_INFO (app_info) ||
+      !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app_info), "DBusActivatable"))
+    return FALSE;

`app_info` is leaked on this error path.
Comment 14 Philip Withnall 2017-10-05 11:36:22 UTC
Review of attachment 351539 [details] [review]:

This looks pretty tenuous, but if it actually works as a workaround, then let’s push it to master with fixes for these two review comments; and then work on fixing the issue properly.

::: gio/gio-tool-open.c
@@ +32,3 @@
 
+static gboolean
+get_bus_name_and_path_from_uri (char *uri,

`const char *uri`

@@ +61,3 @@
+  if (app_info == NULL || !G_IS_DESKTOP_APP_INFO (app_info) ||
+      !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app_info), "DBusActivatable"))
+    return FALSE;

`app_info` is leaked on this error path.
Comment 15 Philip Withnall 2017-10-05 11:36:22 UTC
Review of attachment 351539 [details] [review]:

This looks pretty tenuous, but if it actually works as a workaround, then let’s push it to master with fixes for these two review comments; and then work on fixing the issue properly.

::: gio/gio-tool-open.c
@@ +32,3 @@
 
+static gboolean
+get_bus_name_and_path_from_uri (char *uri,

`const char *uri`

@@ +61,3 @@
+  if (app_info == NULL || !G_IS_DESKTOP_APP_INFO (app_info) ||
+      !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app_info), "DBusActivatable"))
+    return FALSE;

`app_info` is leaked on this error path.
Comment 16 Philip Withnall 2017-10-05 11:36:26 UTC
Review of attachment 351539 [details] [review]:

This looks pretty tenuous, but if it actually works as a workaround, then let’s push it to master with fixes for these two review comments; and then work on fixing the issue properly.

::: gio/gio-tool-open.c
@@ +32,3 @@
 
+static gboolean
+get_bus_name_and_path_from_uri (char *uri,

`const char *uri`

@@ +61,3 @@
+  if (app_info == NULL || !G_IS_DESKTOP_APP_INFO (app_info) ||
+      !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app_info), "DBusActivatable"))
+    return FALSE;

`app_info` is leaked on this error path.
Comment 17 Philip Withnall 2017-10-05 12:17:52 UTC
Er, not quite sure what happened with the quadruplicate review submission there, sorry.
Comment 18 Ondrej Holy 2017-10-05 14:15:53 UTC
Created attachment 360964 [details] [review]
gio: Add hack to close up dbus-daemon race

Updated as per review...
Comment 19 Ondrej Holy 2017-10-05 14:21:50 UTC
Comment on attachment 360964 [details] [review]
gio: Add hack to close up dbus-daemon race

Attachment 360964 [details] pushed as 1508db2 - gio: Add hack to close up dbus-daemon race

May I push it also in stable?

Letting this bug open as a tracker for a proper fix...
Comment 20 Philip Withnall 2017-10-05 14:45:07 UTC
(In reply to Ondrej Holy from comment #19)
> Comment on attachment 360964 [details] [review] [review]
> gio: Add hack to close up dbus-daemon race
> 
> Attachment 360964 [details] pushed as 1508db2 - gio: Add hack to close up
> dbus-daemon race
> 
> May I push it also in stable?

Yes, that would be sensible. Please push to the glib-2-54 branch. Thanks.
Comment 21 Ondrej Holy 2017-10-05 15:37:54 UTC
Pushed to stable.
Comment 22 Fan, Chun-wei 2017-10-07 02:48:20 UTC
Created attachment 361080 [details] [review]
Fix building gio-tool-open.c on Windows/Cocoa

Hi,

This is the patch to fix the build of gio-tool-open.c on Windows/Cocoa, which was broken by attachment 360964 [details] [review].

With blessings, thank you!
Comment 23 Philip Withnall 2017-10-07 07:03:01 UTC
Review of attachment 361080 [details] [review]:

++, thanks for the fix
Comment 24 Fan, Chun-wei 2017-10-09 01:13:53 UTC
Review of attachment 361080 [details] [review]:

Hi Philip,

Thanks, I have pushed the patch as:
master: 2c6c032
glib-2-54: a804fcb

With blessings, thank you!
Comment 25 Fan, Chun-wei 2017-10-09 01:14:34 UTC
Review of attachment 361080 [details] [review]:

Hi Philip,

Thanks, I have pushed the patch as:
master: 2c6c032
glib-2-54: a804fcb

With blessings, thank you!
Comment 26 Fan, Chun-wei 2017-10-09 01:14:34 UTC
Review of attachment 361080 [details] [review]:

Hi Philip,

Thanks, I have pushed the patch as:
master: 2c6c032
glib-2-54: a804fcb

With blessings, thank you!
Comment 27 pedrum 2017-12-12 00:44:36 UTC
Thanks Ondrej!

I've been hitting this issue for a while (on Arch) and used the double call to 'gio open' to workaround.

I appreciate your perseverance on this issue (starting 2+ years ago on ticket 
#746534). 

I never would've figured the dbus hanging call relationship here.
Comment 28 Simon McVittie 2017-12-18 13:14:11 UTC
(In reply to Simon McVittie from comment #12)
> Actually, dbus-daemon can't completely fix this - there is a race condition
> in which the dbus-daemon might never have even seen the activating message.

Based on this reasoning, I don't think this is a dbus bug: whatever happens, the GIO code path involved needs to wait at least long enough to be sure that the message has reached the dbus-daemon, and there is nothing that changes to the dbus-daemon can do about this part, because at this stage it can't even know that it is about to be asked to do something.

If GIO is being modified to wait at least that long, it might as well also wait until the message is delivered to the final recipient (I suspect that waiting for the message to reach the dbus-daemon, without also waiting for it to be delivered to the final recipient, would actually be harder to implement).
Comment 29 Philip Withnall 2017-12-21 10:46:45 UTC
Thanks for the analysis, Simon.

Ondrej, would you be able to find time to fix g_app_info_launch_default_for_uri_async() to make it wait for the D-Bus messages to finish round-tripping, as per comment #12 and comment #28?
Comment 30 René Genz 2018-02-21 23:03:08 UTC
Does this bug report cover the following case?
If not I will create a new one.

In Fedora 26 and Fedora 27 in an Xfce session gedit is set as the default program to open text/plain MIME type files. Execution of `xdg-open test.txt` works only every 2nd try (sometimes 3rd try).

In Xfce `bash -x xdg-open test.txt` and `strace xdg-open test.txt` create the same output for un- and successful attempts with gedit as default program.

On the same computer, same user and files, in a GNOME session `xdg-open test.txt` gedit is started every time.

On the same computer, same user and files, in an Xfce session and with a different program, f.e. mousepad or LibreOffice, set to open text/plain files, `xdg-open test.txt` opens the file with that application every time.
Steps to change default program for text files in Xfce session:
1. $ thunar
2. right mouse button click on text file -- Properties...
3. General -- Open with: <select program>
4. [Close]
Comment 31 Ondrej Holy 2018-02-22 09:52:43 UTC
xdg-open uses exo-open on xfce, which uses g_app_info_launch/g_app_info_launch_uris, so it seems that exo-open also needs similar workaround as it has been used for "gio open", or provide proper fix for g_app_info_launch* as noted in Comment 29.
Comment 32 Ondrej Holy 2018-02-22 10:00:19 UTC
(In reply to Philip Withnall from comment #29)
> Ondrej, would you be able to find time to fix
> g_app_info_launch_default_for_uri_async() to make it wait for the D-Bus
> messages to finish round-tripping, as per comment #12 and comment #28?

To be honest I am not sure I am able to make something better than:
https://bug746534.bugzilla-attachments.gnome.org/attachment.cgi?id=300674

Don't you have any idea how to be sure that D-Bus messages finish round-tripping and do not use _sync calls as in that attachment?

See also reasoning why this patch was rejected and why the workaround was introduced:
https://bugzilla.gnome.org/show_bug.cgi?id=746534
Comment 33 Philip Withnall 2018-02-22 12:43:18 UTC
(In reply to Simon McVittie from comment #10)
> Review of attachment 351539 [details] [review] [review]:
> 
> ::: gio/gio-tool-open.c
> @@ +156,3 @@
>  
> +      /* FIXME: This chunk of madness is a workaround for a dbus-daemon bug.
> +       * See https://bugzilla.gnome.org/show_bug.cgi?id=780296
> 
> If you believe this to be a dbus-daemon bug, please report it on dbus' bug
> tracking system.

After re-reading bug #746534, it looks like this is a combination of a dbus-daemon bug, and gio-open possibly not waiting to flush its pending D-Bus messages.

The D-Bus bugs are about service activations being dropped on the floor if the peer which triggered them exits:
 - https://bugs.freedesktop.org/show_bug.cgi?id=896
 - https://bugs.freedesktop.org/show_bug.cgi?id=52372

(In reply to Simon McVittie from comment #28)
> (In reply to Simon McVittie from comment #12)
> > Actually, dbus-daemon can't completely fix this - there is a race condition
> > in which the dbus-daemon might never have even seen the activating message.
> 
> Based on this reasoning, I don't think this is a dbus bug: whatever happens,
> the GIO code path involved needs to wait at least long enough to be sure
> that the message has reached the dbus-daemon, and there is nothing that
> changes to the dbus-daemon can do about this part, because at this stage it
> can't even know that it is about to be asked to do something.

The GDesktopAppInfo code does call g_dbus_connection_flush() after it sends its method call to the bus. There are two issues here though:
 - It doesn’t block on returning from flush, so the main loop could be exited before the flush operation completes (although would it ever take more than one main context iteration to flush a single message?) — this may not be the problem in practice.
 - If the code is going to flush, it might as well just block in g_app_info_launch*() until the D-Bus Open/Activate method call completes. They’re roughly equivalent, but the behaviour of blocking on the method call completion is a lot easier to reason about.
Comment 34 Philip Withnall 2018-02-22 12:46:00 UTC
(In reply to Ondrej Holy from comment #32)
> (In reply to Philip Withnall from comment #29)
> > Ondrej, would you be able to find time to fix
> > g_app_info_launch_default_for_uri_async() to make it wait for the D-Bus
> > messages to finish round-tripping, as per comment #12 and comment #28?
> 
> To be honest I am not sure I am able to make something better than:
> https://bug746534.bugzilla-attachments.gnome.org/attachment.cgi?id=300674
> 
> Don't you have any idea how to be sure that D-Bus messages finish
> round-tripping and do not use _sync calls as in that attachment?
> 
> See also reasoning why this patch was rejected and why the workaround was
> introduced:
> https://bugzilla.gnome.org/show_bug.cgi?id=746534

On the basis of comment #33 in this bug, I think your attachment #300674 [details] is probably the right approach. For the synchronous g_app_info_launch*() APIs, we already block on file I/O, so blocking on the bus is not a massively longer stretch. For the asynchronous g_app_info_launch*_async() APIs, we should yield on the g_dbus_connection_call() callback (but not synchronously block on it).
Comment 35 Simon McVittie 2018-02-22 13:50:28 UTC
(In reply to Philip Withnall from comment #33)
> After re-reading bug #746534, it looks like this is a combination of a
> dbus-daemon bug, and gio-open possibly not waiting to flush its pending
> D-Bus messages.
> 
> The D-Bus bugs are about service activations being dropped on the floor if
> the peer which triggered them exits:
>  - https://bugs.freedesktop.org/show_bug.cgi?id=896
>  - https://bugs.freedesktop.org/show_bug.cgi?id=52372

These bugs have a somewhat confused history of similar symptoms with different root cases, particularly #896. I'd be happy to review a proposed solution for #52372, which might be the last part of #896 remaining (or not, depending how lucky we are).

Solving #52372 would be enough for the specific case of a GApplication, but isn't enough if the first thing the process receiving the method call does is to turn round and ask for information about the sender, which will no longer be available because the sender no longer exists (<https://bugs.freedesktop.org/show_bug.cgi?id=52372#c11>). This mainly applies to the system bus, but potentially also Flatpak portals.

I'm also not sure whether solving #52372 is going to be as simple as one might think: to make it work, we would need to make sure the dbus-daemon holds onto all the information necessary to process <allow> and <deny> rules for as long as there are any pending activation attempts for this connection, even if we have already received the Disconnected notification for this connection; and we would need to make sure that information can be looked up from a DBusConnection reference cached in the pending activation data structure, and is never looked up in the dbus-daemon's { unique name => DBusConnection } map, because the connection would have already left that map when it got disconnected.

> The GDesktopAppInfo code does call g_dbus_connection_flush() after it sends
> its method call to the bus. There are two issues here though:
>  - It doesn’t block on returning from flush, so the main loop could be
> exited before the flush operation completes (although would it ever take
> more than one main context iteration to flush a single message?) — this may
> not be the problem in practice.

I think flush() just posts a message to the GDBus worker thread, and doesn't do any I/O in the main thread. We can't know whether the GDBus worker thread has had any CPU cycles scheduled unless we wait for it to ack the flush request.

>  - If the code is going to flush, it might as well just block in
> g_app_info_launch*() until the D-Bus Open/Activate method call completes.
> They’re roughly equivalent, but the behaviour of blocking on the method call
> completion is a lot easier to reason about.

I'm inclined to agree, at least for the async case. This would completely bypass any weird dbus-daemon behaviour around connections falling off the bus with messages still queued for delivery.

My suggestion in earlier comments was to only change the async case, then make sure the gio tool uses it, but not change the sync case - because the sync case is something that applications already block on, and extending the blocking period to "until the launched app replies" seems questionable.

What we really want here, as far as I can see, is to block until the dbus-daemon is known to have dispatched our message (but no more). If we had a solution for #52372, we could do something like this:

* send async activation message that will auto-start the target app
* send Ping() to dbus-daemon
* wait for Ping() reply
* stop blocking in sync() call or complete async() call

... but waiting for a reply from the *app* seems both simpler and more robust than that.
Comment 36 Philip Withnall 2018-02-22 14:07:09 UTC
(In reply to Simon McVittie from comment #35)
> Solving #52372 would be enough for the specific case of a GApplication, but
> isn't enough if the first thing the process receiving the method call does
> is to turn round and ask for information about the sender, which will no
> longer be available because the sender no longer exists
> (<https://bugs.freedesktop.org/show_bug.cgi?id=52372#c11>). This mainly
> applies to the system bus, but potentially also Flatpak portals.

I’m happy to consider the case of the auto-launched process asking for information about the sender to be out of scope here. The applications which one is likely to launch using `gio open` are unlikely to ask for that information (although I’m less sure of this in the portals case — in any case, let’s keep it out of scope here to keep things tractable).

> What we really want here, as far as I can see, is to block until the
> dbus-daemon is known to have dispatched our message (but no more). If we had
> a solution for #52372, we could do something like this:
> 
> * send async activation message that will auto-start the target app
> * send Ping() to dbus-daemon
> * wait for Ping() reply
> * stop blocking in sync() call or complete async() call
> 
> ... but waiting for a reply from the *app* seems both simpler and more
> robust than that.

Ack.
Comment 37 René Genz 2018-02-22 22:01:24 UTC
(In reply to Ondrej Holy from comment #31)

I filed a bug report for `exo-open`:
https://bugzilla.xfce.org/show_bug.cgi?id=14237
Comment 38 Ondrej Holy 2018-02-27 10:39:46 UTC
Created attachment 369000 [details] [review]
gdesktopappinfo: Use sync dbus calls to avoid dropping messages

The dbus-daemon can drop a message if we disappeared from the bus immediately
after this call. This is especially problem for "gio open" when trying to
open an application, which is not yet running. Although we don't want to wait
around to see if the program crashed during startup, the non-blocking API can't
be used here. Let's use blocking API with a reasonable small timeout, just to
be sure message is sent.
Comment 39 Ondrej Holy 2018-02-27 10:40:54 UTC
Created attachment 369001 [details] [review]
Revert "gio: Fix gio-tool-open.c on Windows/Cocoa"
Comment 40 Ondrej Holy 2018-02-27 10:41:12 UTC
Created attachment 369002 [details] [review]
Revert "gio: Add hack to close up dbus-daemon race"
Comment 41 Simon McVittie 2018-02-27 12:40:07 UTC
Review of attachment 369000 [details] [review]:

> The dbus-daemon can drop a message if we disappeared from the bus immediately
> after this call

The issue is partly this, and partly that the GDBus worker thread that dispatches the underlying connection isn't guaranteed to have even got as far as sending data to the dbus-daemon (unless we flush it, but if we're going to do that, we might as well wait for the round-trip).
Comment 42 Simon McVittie 2018-02-27 12:57:32 UTC
Review of attachment 369000 [details] [review]:

::: gio/gdesktopappinfo.c
@@ +53,3 @@
 #endif
 
+#define DBUS_CALL_TIMEOUT 250 /* 0.25 sec */

I don't think this is long enough to guarantee that the GDBus thread has been scheduled for long enough to pass the message to the dbus-daemon (on slower machines), or long enough to guarantee that the activated service has been activated, after which the dbus-daemon will do the identity/permission check and deliver the message (on machines with slow I/O it could take a while to get the activated service started).

However, if it was extended to be long enough to guarantee that, then it would block the main thread for an inconveniently long time if the activated service is non-responsive. There's really no good value to use here, unfortunately...

That's why I think the simple API used in random long-running GUIs to implement things like gtk_show_uri_on_window(), and the API used for the special case of `gio open` which we know is going to exit as soon as that API has returned, should probably not be the same thing.

My original suggestion was to make g_app_info_launch_default_for_uri_async() wait for the round-trip, but leave g_app_info_launch_default_for_uri() and similar APIs as-is. This would probably require a bit of additional plumbing between GAppInfo and GDesktopAppInfo, unfortunately.
Comment 43 Ondrej Holy 2018-02-27 14:35:01 UTC
Thanks for your feedback.

g_dbus_connection_flush is already called, but async with NULL callback... so do I understand correctly that we should also use _sync here, resp. wait for the callback?

I worried about the timeout a bit, but it was based on some ancient discussion on #gtk+, but do not recall the details. Let's remove it then...

To be honest, I still don't understand, why we should let g_app_info_launch_default_for_uri to be as is. It is a bug that it fails to spawn an app in some cases. On one hand, g_app_info_launch_default_for_uri does I/O and other _sync calls, on another hand, we are still trying to make it non-blocking. If somebody really wants this unsafe behavior (e.g. gtk_show_uri_on_window), then it can simply use the g_app_info_launch_default_for_uri_async with NULL callback...

I am not GLib maint, but I don't agree that g_app_info_launch_default_for_uri should behave differently than the corresponding async version.

Philip?
Comment 44 Philip Withnall 2018-02-27 14:56:20 UTC
(In reply to Ondrej Holy from comment #43)
> I am not GLib maint, but I don't agree that
> g_app_info_launch_default_for_uri should behave differently than the
> corresponding async version.
> 
> Philip?

The behaviour for the async and sync versions already differs in the amount of error reporting they do when using portals, so I don’t see much of a problem in doing as Simon suggests, and making them behave a bit more differently. The idea is that people could use the sync g_app_info_launch_default_for_uri() to quickly (without blocking) launch a program without caring about success/failure; or they could use the async version to get more detailed error reporting.
Comment 45 Simon McVittie 2018-02-27 15:15:59 UTC
(In reply to Ondrej Holy from comment #43)
> g_dbus_connection_flush is already called, but async with NULL callback...
> so do I understand correctly that we should also use _sync here, resp. wait
> for the callback?

If you wait for a reply then you don't need to flush, because the reply can't happen until the sent message has made it through the D-Bus connection and the dbus-daemon anyway.

If you don't wait for a reply, then there's little point in the flush call unless it's _sync, but then you still suffer from the dbus-daemon forgetting about pending activations (perhaps accidentally, perhaps deliberately, it isn't clear) if the sender goes away before the activated service takes its bus name (fd.o#52372). At some point I should look into how feasible it would be to change that behaviour in dbus-daemon, but I can't say it's very close to the top of my to-do list.

> To be honest, I still don't understand, why we should let
> g_app_info_launch_default_for_uri to be as is. It is a bug that it fails to
> spawn an app in some cases. On one hand, g_app_info_launch_default_for_uri
> does I/O and other _sync calls, on another hand, we are still trying to make
> it non-blocking. If somebody really wants this unsafe behavior (e.g.
> gtk_show_uri_on_window), then it can simply use the
> g_app_info_launch_default_for_uri_async with NULL callback...

That's arguably a bit of a compatibility break: it means the non-async API, which was previously considered the right thing to call in the common case (for instance gtk_show_uri_on_window() in a Help->About... dialog), would no longer be considered to be the right thing to use there.

On the other hand, *any* behaviour change here is arguably a (minor) compat break, and the current semantics can't work particularly well for D-Bus activation anyway, hence this bug (and the differing behaviour with portals). The problem is that the API was designed for fork-and-exec, and D-Bus activation was bolted on later.

> I am not GLib maint, but I don't agree that
> g_app_info_launch_default_for_uri should behave differently than the
> corresponding async version.

I can see how that could be considered undesirably astonishing, but as Philip says, the behaviour is already different for portals anyway.

Possibly this implies that there should be a _sync version that wraps the _async version, like the way g_dbus_connection_close_sync() wraps g_dbus_connection_close(), or something like that?
Comment 46 GNOME Infrastructure Team 2018-05-24 19:26:41 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/glib/issues/1249.