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 746534 - gvfs-open fails to open when run first time
gvfs-open fails to open when run first time
Status: RESOLVED DUPLICATE of bug 780296
Product: glib
Classification: Platform
Component: gio
2.45.x
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
: 748063 751691 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2015-03-20 15:09 UTC by mikey
Modified: 2017-05-10 12:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gdesktopappinfo: use sync call to avoid dropping message (3.29 KB, patch)
2015-03-31 15:37 UTC, Ondrej Holy
rejected Details | Review
gvfs-open: add hack to close up dbus-daemon race (7.09 KB, patch)
2015-05-20 20:27 UTC, Ray Strode [halfline]
none Details | Review
gappinfo: add hack to close up dbus-daemon race (3.38 KB, patch)
2015-05-21 11:59 UTC, Ondrej Holy
none Details | Review
gvfs-open: add hack to close up dbus-daemon race (gnome-3-14) (4.26 KB, patch)
2015-06-09 11:29 UTC, Ondrej Holy
committed Details | Review
gvfs-open: add hack to close up dbus-daemon race (master) (3.84 KB, patch)
2015-06-09 11:30 UTC, Ondrej Holy
committed Details | Review
gappinfo: add hack to close up dbus-daemon race (4.53 KB, patch)
2015-06-09 13:46 UTC, Ondrej Holy
rejected Details | Review

Description mikey 2015-03-20 15:09:18 UTC
Running gvfs-open fails to open the appropriate application the first time it is run unless the application is already running. 

Step, <output>:

1) gvfs-open /home, <nothing>
2) gvfs-open /home, <nautilus /home>
3) gvfs-open ~/Desktop, <nautilus ~/Desktop>

Running "killall nautilus" will reenable the phenomena. 

The same happens for all files types I have tested, eg. "gvfs-open my.txt" does nothing the first time but launches gedit the subsequent times. 

Having the application running before running gvfs-open on the appropriate file type opens the file first time.

I found the following bug report that has some explanation for the issue (comment 5):

https://bugzilla.redhat.com/show_bug.cgi?id=1175719#c5

I have confirmed the behaviour. Running:

dbus-monitor "interface='org.freedesktop.Application'"

Detects no messaging when running for the first time "gvfs-open /home". However the second and subsequent calls produce output like:

method call sender=:1.320 -> dest=org.gnome.Nautilus serial=7 path=/org/gnome/Nautilus; interface=org.freedesktop.Application; member=Open
   array [
      string "file:///home"
   ]
   array [
   ]
method call sender=:1.321 -> dest=org.gnome.Nautilus serial=7 path=/org/gnome/Nautilus; interface=org.freedesktop.Application; member=Open
   array [
      string "file:///home/michael"
   ]
   array [
   ]
Comment 1 Ondrej Holy 2015-03-24 13:52:15 UTC
Thanks for the bug report. I can reproduce it on F21.

Maybe there is relation with Bug 652262, because adding sleep in g_desktop_app_info_launch_uris_internal helps according the downstream bugzilla report, so we exits too early probably...
Comment 2 Ross Lagerwall 2015-03-24 14:48:30 UTC
This happens when it launches the app via dbus. The problem is that it exits before the underlying dbus call properly finishes and so the message doesn't get through properly (I saw this a while ago and forgot to raise a bug).

I think it should be reassigned to glib since the underlying call to open the app is supposed to be a sync call but it hasn't finished by the time we exit.
Comment 3 Ondrej Holy 2015-03-24 15:02:53 UTC
I'm convinced this is bug in gio also, because g_app_info_launch_default_for_uri should return only after the application is executed - I mean in this case after dbus call is sent. But it seems we exit earlier then the call is sent despite g_dbus_connection_flush is called...

Only sync version of g_dbus_connection_call seems to fix this issue, but we don't want to wait for response probably according the comment:
  /* This is non-blocking API.  Similar to launching via fork()/exec()
   * we don't wait around to see if the program crashed during startup.
   * This is what startup-notification's job is...
   */

(gapplication tool also uses _sync version for launching)

Do you have any idea how to fix it?
Comment 4 Ondrej Holy 2015-03-31 15:37:10 UTC
Created attachment 300674 [details] [review]
gdesktopappinfo: use sync call to avoid dropping message

There is a patch to use _sync call with small timeout 250ms (just to be sure message is sent) as a result of discussion on #gtk+.
Comment 5 Matthias Clasen 2015-05-11 16:59:06 UTC
We are calling

g_dbus_connection_flush (session_bus, NULL, NULL, NULL);

after the async call, to ensure the message makes it out on our end before exit(). Is that not working ?
Comment 6 Allison Karlitskaya (desrt) 2015-05-11 17:06:54 UTC
In the case of activation, it's insufficient to flush the bus -- D-Bus has an annoying habbit of discarding messages for pending activations if the sending application has exited.

In light of how difficult it would be to solve this problem, I almost consider that to be a bug in D-Bus...

Particularly when you consider that the message may even have the no-reply-needed flag.  In that case, why does it matter _at all_ if the sender has quit?
Comment 7 Allison Karlitskaya (desrt) 2015-05-11 17:10:59 UTC
In fact, this "no-reply-needed" case is the case we are dealing with here -- we do g_dbus_connection_call with a NULL async callback, which means that the flag is getting set on the outgoing message.

That means that we have to wait for a reply that will never come.  This is a D-Bus bug...
Comment 8 Dan Winship 2015-05-11 17:11:28 UTC
(In reply to Matthias Clasen from comment #5)
> We are calling
> 
> g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
> 
> after the async call, to ensure the message makes it out on our end before
> exit(). Is that not working ?

That's an async call as well though, so presumably we're exiting before it actually gets a chance to flush.
Comment 9 Ray Strode [halfline] 2015-05-11 17:38:08 UTC
there's a related open dbus-daemon bug here, I think:

https://bugs.freedesktop.org/show_bug.cgi?id=896

comment 41 shows the same problem happening with dbus-send, and of course NetworkManager isn't normally activated, so that shows this problem can happen even if the service is already running.
Comment 10 Ondrej Holy 2015-05-12 12:37:08 UTC
Maybe there is "better" dbus-daemon bug report, see:
https://bugs.freedesktop.org/show_bug.cgi?id=52372

So it is probably dbus bug, but it is quite old and still it isn't fixed. But we need to find some solution quickly, because gvfs-open is now pretty unusable... 

gvfs-open works for me every second try, but it can be much worse according the following downstream bug report (10-100 tries is needed to start the application):
https://bugzilla.redhat.com/show_bug.cgi?id=1220349

Wouldn't be solution to apply my patch as a workaround?
Comment 11 Matthias Clasen 2015-05-12 15:02:33 UTC
I think a workaround would have to be a patch to gvfs-open. We don't want to make the gio api effectively synchronous.
Comment 12 Colin Walters 2015-05-14 21:40:22 UTC
(In reply to Dan Winship from comment #8)
> (In reply to Matthias Clasen from comment #5)
> > We are calling
> > 
> > g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
> > 
> > after the async call, to ensure the message makes it out on our end before
> > exit(). Is that not working ?
> 
> That's an async call as well though, so presumably we're exiting before it
> actually gets a chance to flush.

Yeah...if you annotate you'll see that came from:

https://git.gnome.org/browse/glib/commit/?id=d6954c785d635be875b896ac9f4812e400b39455

So I'd say to combine what Dan and Matthias said...try calling g_dbus_connection_flush_sync() (and note the _sync() ) at the end of gvfs-open.c?
Comment 13 Ondrej Holy 2015-05-15 07:14:44 UTC
This was first thing I tried, however calling _flush_sync() doesn't fix it for me :-(

g_dbus_connection_flush documentation claims it should work, but it doesn't work:
"This is useful in programs that wants to emit a D-Bus signal and then exit immediately."
Comment 14 Ray Strode [halfline] 2015-05-15 15:21:41 UTC
it's not going to work because the problem isn't just the message not going out in time, it's the message not getting processed by the dbus-daemon in time.

If you want to work around this in gvfs-open you need to block gvfs until dbus sends a message to you.  It won't send a message for the call made, though, since the call made is no-reply.

The easiest workaround would be to send a synchronous org.freedesktop.DBus.Peer.Ping message before exiting
Comment 15 Ondrej Holy 2015-05-19 11:27:51 UTC
It seems ridiculous to me to do workaround for this in gvfs-open, because we don't have any information whether the application is launched over d-bus, or spawn and also we don't know bus_name and object_patch for the application to send e.g. org.freedesktop.DBus.Peer.Ping as was suggested by halfline...
Comment 16 Ray Strode [halfline] 2015-05-19 12:21:27 UTC
I think it should be sufficient to ping the message bus itself (or do any other call to the message bus).

As I understand it, the race that needs to be closed is the bus daemon dispatching the request before the client closes.  I believe that the bus daemon dispatches requests from a client in order, so if a client makes two requests the first will get dispatched before the second.

So you shouldn't need to ping the activating service, just the bus daemon (but make sure you wait for a reply!).

I realize it isn't pretty, and it's debatable whether the ugliness should go in the glib or gvfs, but unless you want to fix dbus-daemon it's got to go somewhere... and gvfs-open is one of the few programs out there that will hit this bug in practice, because most programs are long lived.
Comment 17 Ray Strode [halfline] 2015-05-20 13:51:10 UTC
So Ondrej looked into this a bit and discovered the bus daemon doesn't implement the Peer interface for /org/freedesktop/DBus .  But if I understand the race correctly, any method should work, so he's going to try GetId instead.
Comment 18 Ray Strode [halfline] 2015-05-20 14:19:29 UTC
fail:

<oholy> but it seems it isn't enought:
<oholy> method call time=1432131083.551780 sender=:1.272 -> destination=org.gnome.Nautilus serial=9 path=/org/gnome/Nautilus; interface=org.freedesktop.Application; member=Open
<oholy>    array [
<oholy>       string "file:///"
<oholy>    ]
<oholy>    array [
<oholy>    ]
<oholy> method call time=1432131083.552294 sender=:1.272 -> destination=org.freedesktop.DBus serial=10 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetId
<oholy> method return time=1432131083.552340 sender=org.freedesktop.DBus -> destination=:1.272 serial=8 reply_serial=10
<oholy>    string "8be56d0183ba3a5ac06b42a8555c26c6"
<oholy> signal time=1432131083.560777 sender=org.freedesktop.DBus -> destination=:1.272 serial=33 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
<oholy>    string ":1.272"
<oholy> id is returned, but nautilus isn't started..
<halfline> well nautilus doesn't have to be started, it just has to be dispatched
<halfline> if i understand the problem right
<halfline> or are you saying you've tried the patch and it isn't working ?
<oholy> sorry, bad formulation
<oholy> nautilus doesn't start with this patch
<halfline> okay
<halfline> hmm
Comment 19 Ray Strode [halfline] 2015-05-20 14:57:30 UTC
So i guess the three obvious choices left are:

1) add the ping to glib
2) add a delayed exit to gvfs
3) fix dbus-daemon
Comment 20 Ray Strode [halfline] 2015-05-20 15:01:40 UTC
1) could better be stated as "block for the reply to finish" but it's not really an option given the api doesn't have an async ready callback
Comment 21 Ray Strode [halfline] 2015-05-20 20:27:44 UTC
Created attachment 303713 [details] [review]
gvfs-open: add hack to close up dbus-daemon race

If gvfs-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.
Comment 22 Ray Strode [halfline] 2015-05-20 20:28:40 UTC
the attachment 303713 [details] [review] is pretty yucky but it closes up the race without changes to glib or dbus-daemon.
Comment 23 Ray Strode [halfline] 2015-05-20 20:40:22 UTC
Review of attachment 303713 [details] [review]:

::: programs/gvfs-open.c
@@ +103,3 @@
+  g_clear_object (&app_info);
+  g_clear_pointer (&basename, g_free);
+  g_clear_pointer (&object_path, g_free);

there's a harmless unnecessary g_clear_pointer here. we should either drop it or add another harmless, unneccessary g_clear_pointer for bus_name.
Comment 24 Ondrej Holy 2015-05-21 11:27:07 UTC
Review of attachment 303713 [details] [review]:

It seems the patch fixes the problem. It also leaks output from g_file_get_uri (I know there is same leak in the gnome-3-14 code, which is already fixed in newer versions). However the patch is the example, why I think it is ridiculous to fix this in gvfs (gvfs-open is almost double sized now and contains lot of copy&pasted code from glib)... :-(
Comment 25 Ondrej Holy 2015-05-21 11:59:47 UTC
Created attachment 303751 [details] [review]
gappinfo: add hack to close up dbus-daemon race

Might be better to fix it in g_app_info_launch_default_for_uri, which is already using synchronous I/O, to safe some copy&pasted code, mightn't it?
Comment 26 Ondrej Holy 2015-05-21 12:01:19 UTC
Review of attachment 303751 [details] [review]:

::: gio/gappinfo.c
@@ +21,3 @@
 #include "config.h"
 
+#include <string.h>

is redundant
Comment 27 Ray Strode [halfline] 2015-05-21 12:47:44 UTC
Review of attachment 303751 [details] [review]:

well, Matthias / Ryan can chime in on whether or not this is acceptable, but it makes sense to me as a "right now" answer. Some might argue that extending the GAppInfo interface would be better, but I think doing that would only make sense if we did it in a way that fixed the three warts in the existing async api (no callback, no cancellable, GList of strings instead of array of strings).

I also disagree that putting a workaround in gvfs-open is ridiculous. Yucky, but good enough near-term, since it's one of the very few programs that would ever be affected.

::: gio/gappinfo.c
@@ +729,3 @@
+      const char *app_id;
+
+      app_id = g_desktop_app_info_get_app_id (app_info);

I think if you're going to be introducing private api between gappinfo and gdesktopappinfo it should be as contained as possible.  e.g., g_desktop_app_info_ping_peer_sync rather than exporting the app id and the api for converting the app id into an object path

::: gio/gappinfoprivate.h
@@ +26,3 @@
+gchar *object_path_from_appid (const gchar *app_id);
+
+const char *g_desktop_app_info_get_app_id (GAppInfo *appinfo);

this should probably go in its own header i think.
Comment 28 Allison Karlitskaya (desrt) 2015-05-21 18:31:42 UTC
Review of attachment 303713 [details] [review]:

So this is okayish, but a couple of comments:

 1) in addition to checking if the desktop file looks like a bus name you should check the DBusActivatable key to make sure it is true.

 2) at this point you almost may as well send the Open or Activate method for yourself...

 3) it could make sense to add some sort of g_app_info_sync() sort of call to deal with this, but...
    ...that would be silly, if eventually this will be fixed in D-Bus

so, really, just check DBusActivatable and I guess this is the best we can do.
Comment 29 Emmanuele Bassi (:ebassi) 2015-05-24 20:58:47 UTC
*** Bug 748063 has been marked as a duplicate of this bug. ***
Comment 30 Cosimo Cecchi 2015-05-24 21:03:39 UTC
I wrote another set of similar patches on bug 748063 that try to fix the problem in gdesktopappinfo.c itself.
Comment 31 Ondrej Holy 2015-06-09 11:26:36 UTC
Comment on attachment 300674 [details] [review]
gdesktopappinfo: use sync call to avoid dropping message

Changing status of Attachment 300674 [details] as per Comment 11.
Comment 32 Ondrej Holy 2015-06-09 11:27:40 UTC
Review of attachment 303713 [details] [review]:

::: programs/gvfs-open.c
@@ +61,3 @@
+
+  if (app_info != NULL && !G_IS_DESKTOP_APP_INFO (app_info))
+    return FALSE;

This check can be omitted...

@@ +197,3 @@
+	  char *object_path = NULL;
+
+	  if (get_bus_name_and_path_from_uri (g_file_get_uri (file), &bus_name, &object_path))

This works only if location is relative or absolute path. File is NULL if location is proper uri...
Comment 33 Ondrej Holy 2015-06-09 11:29:02 UTC
Created attachment 304844 [details] [review]
gvfs-open: add hack to close up dbus-daemon race (gnome-3-14)

Let's fix it in gvfs-open, there is amended patch from halfline with removed unnecessary g_clear_pointer, fixed uri leak, removed redundant app_info check, fixed for uri locations.
Comment 34 Ondrej Holy 2015-06-09 11:30:15 UTC
Created attachment 304845 [details] [review]
gvfs-open: add hack to close up dbus-daemon race (master)
Comment 35 Ray Strode [halfline] 2015-06-09 12:21:16 UTC
Review of attachment 304844 [details] [review]:

So I'm clearly okay with this patch, and it looks like you addressed all the things Ryan said. I will say, though, that I sort of like your approach in attachment 303751 [details] [review] better (well with the changes I mentioned).  It doesn't make an async api suddenly synchronous so it addresses mclasen's concern in comment 11.  It isn't 'pretty', but workarounds seldom are.  Anyway, either way seems okayish to me, and if you just want to do it in gvfs, that's cool.  Still, might be worth pinging mclasen/ryan one more time to get their takes on comment 25.
Comment 36 Ondrej Holy 2015-06-09 13:46:42 UTC
Created attachment 304862 [details] [review]
gappinfo: add hack to close up dbus-daemon race

Ok, there is also modified fix for gappinfo for comparation.
gdesktopappinfoprivate.h is added and g_desktop_app_info_ping_peer_sync is introduced...
Comment 37 Allison Karlitskaya (desrt) 2015-06-09 15:12:03 UTC
Review of attachment 304862 [details] [review]:

This effectively causes the call to block, which is really in no way better than just doing a blocking D-Bus call in the first place...

I really think any fix needs to be done inside of the commandline tool itself.
Comment 38 Ray Strode [halfline] 2015-06-09 15:17:53 UTC
that call already blocks
Comment 39 Ray Strode [halfline] 2015-06-09 15:41:14 UTC
<halfline> desrt: g_app_info_launch_default_for_uri is documented as a sync call
<desrt> oh.  curious.
<desrt> still not a fan :(
<desrt> opening a file on the disk and reading a couple of bytes is not the same as blocking on an app to startup
<halfline> not the same, but both can result in the program seemingly freezing up
<halfline> anyway, the workaround is ugly no matter where it goes, and i don't really care where it goes
Comment 40 Ondrej Holy 2015-06-12 06:29:19 UTC
Ok, so, I'm resigned to push the gvfs-open patches...
Comment 41 Ondrej Holy 2015-06-12 06:29:52 UTC
Comment on attachment 304844 [details] [review]
gvfs-open: add hack to close up dbus-daemon race (gnome-3-14)

gnome-3-14:
commit 7bee91695bbe5d9228392e6da496186f02df5c39
Comment 42 Ondrej Holy 2015-06-12 06:30:14 UTC
Comment on attachment 304845 [details] [review]
gvfs-open: add hack to close up dbus-daemon race (master)

master:
commit 9de6328f97a75b3ac4431810b33605f75778f1f2

gnome-3-16:
commit 9297474c33192fe210f0cbc9ffc349f19604516a
Comment 43 Ondrej Holy 2015-06-12 06:33:47 UTC
Thanks to all participants!
Comment 44 Cosimo Cecchi 2015-06-27 03:09:12 UTC
-> glib

Reopening and moving to GLib, because I'm now hitting the same exact issue when my application (Sushi) calls gtk_show_uri() and immediately quits afterwards. If the application is DBus-activated, its window won't be shown until gtk_show_uri() is called a second time.

My patches from bug 748063 (or other similar patches that fixed this at the GLib level) would fix this problem.
Comment 45 Ondrej Holy 2015-06-30 06:15:05 UTC
*** Bug 751691 has been marked as a duplicate of this bug. ***
Comment 46 Ondrej Holy 2015-08-10 09:03:04 UTC
It seems to me gtk-launch utility has also same problem...
Comment 47 Ray Strode [halfline] 2016-03-04 15:12:25 UTC
filed bug 763103 for gtk-launch
Comment 48 Mark Blakeney 2017-04-30 01:52:30 UTC
As per https://bbs.archlinux.org/viewtopic.php?id=190252 this bug existed since GNOME 3.14 and was finally fixed about 1 year later in GNOME 3.17.3. However, since GNOME 3.24, gvfs-open has been depreciated and we are supposed to use gio open. But gio open has this same old bug :( Calling gio open only works when Nautilus is already running so presumably the same fix done to gvfs-open (https://github.com/GNOME/gvfs/commit/9de6328f97a75b3ac4431810b33605f75778f1f2) needs to be done to gio.
Comment 49 Mark Blakeney 2017-05-09 22:13:25 UTC
I just discovered bug 780296 is more appropriate to my comment above. The responsible developer should close this bug here given gvfs-open has been depreciated away now since GNOME 3.24.
Comment 50 Ondrej Holy 2017-05-10 12:26:12 UTC

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