GNOME Bugzilla – Bug 133243
"Run Application" temporarily hangs when user starts typing
Last modified: 2015-03-24 13:00:49 UTC
Description of Problem: (using gnome 2.4) When I click on "Run Application" from the main menu, as soon as I hit a letter on the keyboard it freezes up as if it were searching for something. Sometimes it takes as long as 20 seconds to allow me to finish typing. After I try it again it goes much faster. This only happens after a few hours of not using my computer. Steps to reproduce the problem: 1. Wait a few hours 2. Click "Run Application" from the gnome menu 3. Type something Actual Results: Application hangs while searching harddisk for something, can't type anything until it finishes. Expected Results: It should allow me to type something the instant it comes up How often does this happen? Only when the computer hasn't been used for a few hours. Additional Information: It seems to me as if it is searching the harddisk for matches to what I am typing so that it can do the auto-competion thing, but for some reason it takes much longer than it should.
For me this happens too. It is most visible if I open the "Run Application" with keyboard shortcut (Alt F2 in my case) and try to type anything in, dialog (and panel) freezes up to minute. When I work with mouse only (choose from popup with command history etc.), everything is fine. When I strace gnome-panel, I see, that as soon as I try to type in, it opens all directories in my PATH and tries to access (ie. access("/usr/bin/prune", X_OK) = 0) all the executables there (which is about 3100 in my /usr/bin). I use debian testing, curently with 2.6.x kernel, but 2.4.x is the same.
I can confirm the same for gnome 2.4 in gentoo stable on x86.
The problem here, as noted, is that in order to fill g_complete every file in the user's path is access'd and stat'd. This happens once everytime the run dialog is created. On some systems this takes a long time to complete (10-20 seconds on my old PIII 650 latop with gentoo). However, once the kernel has cached the inodes it is much faster to run in the future. Here are some possibilities that I'm thinking of: - When the panel is loaded stat all of the files in the user's path. This can be added with low priority to the idle loop and will likely be completed before the user uses the run dialog. * This has the disadvantage of slowing the startup of gnome. - Instead of regenderating the g_complete object each time, we could save it with all of its entries for the next time the run dialog is called. * This has the disadvantage of added complexity for checking if files have been linked or unlinked in the user's path. We could save the mtime of each path dir and regenerate on demand if the mtime has changed. - Be less precise about which files were autocomplete. Instead of calling access and stat on each file, we could just throw everything from readdir into g_complete. * This has the disadvantage of autocompleting some files that might be directories or non-executable. But this would be rar due to the nature of the dirs in PATH. None of these solutions seem ideal, but this really is a problem on some systems.
Ross: the GCompletion object is filled only the first time the run dialog is opened, AFAIK. So the idea is, the first time the user uses the dialog, you fill the GCompletion object with a function added to the idle loop. So the GCompletion object is filled only if necessary, and it doesn't block the UI. What do you think of that?
Vincent: I've just verified that the GCompletion object is filled everytime the dialog is opened. I tested out putting panel_run_dialog_ensure_completion() into the idle loop. Unfortunately I don't think this will give the desired effect. What happens is: (1) user starts typing (2) panel_run_dialog_ensure_completion is placed in the idle loop (3) User maybe types another char or two before the idle loop calls ensure_completion (4) ensure_completion runs until it's finished blocking user input You can simulated this by putting sleep(1) into the fill executables function if your machine is too fast to notice otherwise (as mine is). I might be missing something here, so I'll attach the idle add patch for you to double check. Here's another idea (that avoids using threads): Initially just use readdir to place all of the interesting files into a list. This saves us the two calls to access and stat and I *think* will be very fast. Then, using a function in the idle loop, batch process the interesting file list checking with access and stat to see if we want to use them for GCompletion. Batches can be handled say 100+ or so at a time until done. After a batch is done it can be added to the GCompletion object, allowing possible completions to be incrementally available. This should prevent blocking user input on slower systems.
Created attachment 25125 [details] [review] idle add ensure_completion patch
I've created a patch to try out my last thought about handling the stat and access in batches. It seems to work well on my machine, but it's rather fast. If someone who has been suffering from this bug would like to try it out that would be appreciated. Also, you might want to play with the batch size. Right now it's 100, but that might still be too large and ruin the feeling of interactive typing.
Created attachment 25129 [details] [review] fill GCompletion object in batches
My machine is an athlo XP 1800, not a "slow" machine (imho). I just used the Run dialog after a few days of not touching my computer, and it took about 10 seconds after I typed the letters "gca" to get gcalctool. Would this really be something that processor speed has much of an impact on, or would it have more to do w/ HD seek times, or filesystem-related stuff? Anyways, I'm not a developer, but I think it would be best if the "completion" items load as soon as the run dialog is opened, (before user starts typing) and gives some indication or message that it is searching the user's path.
Ross: I think the second patch is not what we want. Let's try this: * in panel_run_dialog_present() you add a function in the idle loop to search for executables. * in entry_event() the autocompletion stuff happens only when this function has ended (you can use a gboolean like completion_ended for that). If the function has not ended, we just skip the autocompletion stuff. This should not block the UI. * when the function ends, if there the user typed some characters, then do the autocompletion.
Vincent: I'll give that a try later today. I think that I might be missing something fundamental about how glib's idle loop works. It's single threaded, right? When a function is selected from the idle queue will it run until completion, blocking other events? Or does glib give it a max time slice? My impresssion was that once an idle handler starts running it will go until it's finished. That's why I'm thinking that our problem here is not g_completion_complete() blocking the UI, but rather that the filling function blocks the UI because it takes too long to run, sometimes.
Ross: you're absolutely right and I was wrong :-) I should have thought a bit before writing this comment. Ok... Maybe we should try with g_main_context_iteration(). Hrm... I don't have a lot of time right now to look at this. Maybe tomorrow.
Vincent: using g_main_context_iteration() seems like a big patch because we would have to muck with the event loop for the whole panel app. Naturally, I'm going to give a voice of support for patch that I posted above (batches) :-). This patch was just a proof of concept, and I realize that it contains at least one bug. With a few tricks, though, it can be done in the amount of space as is currently used - by working on the dialog.executables list in reverse and giving g_completion_add_items() a pointer to first available valid completion executables list: full paths to access and stat tested good basenames --------------------------------|----------------------- ^ | g_completion_add_items(|)
Below is a fixed version of the batch patch. It uses the same amount of space as the original since it works on the list in place intead of creating a new list. I tested this on my old PIII laptop with gentoo. The run dialog used to be unusable for 10-15 seconds. Now it's more or less interactive (there are a few brief pauses when typing). More testers would be appreciated.
Created attachment 25185 [details] [review] Updated batch patch
With concern of slow computer, my is Duron 1300 with 256MB of mem, which I do not consider that slow and in my case, first use of Run after not using is for a while is at least half a minute, which makes it totaly useless. But as I wrote before, the problem is the amount of files that have to be stated. I thing the main problem is the behaviour itself. I use run dialog becouse I want to run some app quickly and in most cases I do not need autocomplete because commands are usually short. So I think it's wrong to autocomplete here until I ask to (something like TAB key in bash, but problem here is, that its used for something else). So my requirements for Run diaalog are: 1) start as fast as possible 2) and let my write in any command immediately 3) if i ask for it, try to autocomplete If it doesn't interfere with first two requirements, its of course possible to build list of possible autocompletes. I hate to wait for something I very rarely use. Just my point of view.
Using both access and stat sounds silly to me. stat should be enough. That being said, I think the readdir direction is better. Just fill in the cache with all names in the path, executable or not. Initially all names are mapped to "maybe". Later, when and if someone wants to complete "fo", then go out and stat all "maybe" entries starting with "fo". Those that are executable get changed to "yes", the rest get deleted. That should be ~20x faster. And it's not hard.
Created attachment 27713 [details] [review] Patch to limit stat to only what we need There you go. Testing welcome. Notice, that I didn't even resolve the access issue.
*** Bug 142895 has been marked as a duplicate of this bug. ***
Frank: any thoughts on this?
I think the problem here might be power management where the harddrive spins down. That's why it doesn't work for some people after not using their computer for a while. I don't use PM, so my drive never spins down and I never see this problem. I've got an Athlon 700, 512MB mem. My computer is old compared to the machines other people have, so I highly doubt it is general hard drive seek times. If the problem really is PM, then even just stating what we need wont help because the drive will still need to spin up. Nautilus does completion by loading all files in whatever directory you are completing in. It also has to stat the files, so I bet Nautilus is also slow the first time after not using your computer for a while. Maybe someone who has run dialog problems could test that. Anyway, if PM is a problem and it also affects just reading a directory, without doing access/stat, then I'm not sure what the best solution is. Otherwise I think just adding everything in $PATH is easiest, normally everything in there is gonna be an executable. The patch I added to HEAD that completes on files/directories is another problem, since it has to stat the same way that Nautilus does. But maybe directories with only a few items aren't a big deal?
I simply don't believe PM is the problem. You can *hear* PM in action. The problem here is that the run dialog goes out and stats thousands of files. That will always take a while, but when you have left the computer along for a while it will take even longer as directory metadata in caches have likely been tossed. (Obviously things are even worse if the drive has to spin up.) Please run under strace and ask yourself if the observed behaviour is reasonable, even if on your computer it happens to finish fast enough not to be a problem. You can simulate the situation by running under valgrind -- instant processor downgrade, :-) Alternatively, put some NFS directory into your PATH. The solution here is not to do things we don't have to. In this case, when we need completions for "d", don't stat files that don't start with "d". That's a simple and very effective solution. To summarize: thing that make this a problem: * Slow computers. * PATH no longer in kernel's cache. * Long PATH, lots of files in PATH. * Slow file systems, notably remote ones. For reference, if I hit <tab> twice in a shell, I get asked about 3438 possible completions.
FWIW, I just briefly looked at the bash source and it also does access/stat on every file in PATH as it tab-completes until it finds a match. So if you just hit tab twice that would mean it accesses/stats every file, unless I misunderstood the code. After stating once it keeps the info in a hashtable for future use. That means to me it is not simply a slow computer problem. As mentioned before, the people who experience this problem don't have slow computers and it only happens for them after they don't use their computer for a long time. I still think it might be PM related, but I can't get my drive to spin down, so I can't test it. I bet that if you start a new shell, walk away from your computer, and double-tab as soon as you come back you will experience the same slowness. Of course that still doesn't solve the problem or address the issue of slow filesystems. - Frank
I found out, that one of the reasons it took too long on my (I believe faily fast computer) was partly filesystem problem. After I changed from jfs to other filesystem, it changed from unusably long to long. And to bash. The difference is, that in bash, you do not have to hit tab twice to write any command. My only objection is, that Run dialog tries to be smarter then me. I know, when I need completition, I know when I do not need it.
I just checked using strace what bash actually does. If you type "d" <tab>, then it stats everything in the path starting with "d". That's first of all <5% of all files -- thus 20x speedup -- and secondly happens only when asked for.
I noticed that even the window for "Run application" takes some time to load. So my 2c of how I would like it to behave: 1) start as fast as possible 2) and let my write in any command immediately 3) autocomplete if set as an option (ala-KDE) KDE has different options about autocompletion, which I suppose that, in our case, can be defined according to the slowness one is happy to accept to have, for example, automatic autocompletion (like right now), or TAB-triggered autocompletion (ala-bash)... Just my point of view.
Created attachment 28671 [details] [review] patch for CVS head Here's a patch for CVS head that will only stat items that match the prefix the user entered. Testing welcome. CVS head also autocompletes on files/directories. Hopefully this will be fast enough so that we don't have to add an option to turn it off.
*** Bug 123644 has been marked as a duplicate of this bug. ***
I'm seeing the same behaviour on Gnome 2.6 on Gentoo current. IMHO, only searching for executable names after the first letter has been typed is a perfectly good solution. Why search for all the executables if 95% of them is going to be discarded the moment someone types a single letter?
Marking AP4 to reflect accessibility impact.
Apologies for spam-- ensuring Sun a11y team are cc'ed on all current a11y bugs. Filter on "SUN A11Y SPAM" to ignore.
gmrun has pretty much good behaviour: http://sourceforge.net/projects/gmrun much better than "Run Application" in the same computer with the same conditions.
Frank: you don't need approval for patches to your own code :-) The fact that the run dialog uses the new menu code may have made this better, or indeed may have made it worse. It feels a little better to me, though.
Hi Mark ... haven't done any Gnome coding in a while so my environment isn't really setup. I would appreciate it if you could review/commit this. I don't fully trust my C skills either! :-)
Hi, I have this problem on an athlon 2200+, 512 mb ddr, and a maxtor 7200 rpm ata/100 drive. I don't use any form of power management (my hard drive stays on all the time). Hope that helps. :)
I'm still seeing this problem in Gnome-2.8. I have several workmates that also agree...
Yep, it seems to be still in 2.8. Could we - at least - have the autocompletion as an option somewhere so that those of us that don't want/need it can switch it off until it is fixed?
See bug #152025. Patches are welcome.
But is this bug here blocking on someone reviewing Frank's patch? Vincent, could you find time to do that? Anyone else?
I'm planning to review the patch before the 2.9.91 release... (note that this bug is 2.10.x targeted)
Great. Won't that hopefully remove the argument for the option to turn off this feature?
I'm not sure. I have plans to make a "reduced resource" mode for the panel...
Hi. I'm not sure if my patch still applies cleanly. If someone wants to update it, I'm sure Vincent or Mark will apply it. I pretty much dropped the ball on this one, sorry about that. Should have applied the patch ASAP back then - don't really have time for it these days. :-(
I committed a modified version of Frank's patch. Tests are welcome.