GNOME Bugzilla – Bug 348289
Filechooser is blocked by higher priority idle
Last modified: 2018-02-10 03:35:55 UTC
If some idle is running, then new filechooser doesn't show files until that idle stops. Examples of such idle are GtkTextView computing lines, GtkPrintOperation, or GtkSourceView. "some idle" above means some higher priority idle, I guess. Not sure it's relevant, but idle functions in gtkfilesystemunix.c are one-time, so they could use high priority to avoid this problem. The simplest way to reproduce is: 1) create 2,000,000-lines file (much less is really needed, but two millions should be enough for everyone), e.g. with python -c 'open("/tmp/file", "w").write("\n"*2000000)' 2) open it in gedit 3) hit Ctrl-O to open file chooser dialog. Result: blank filechooser (see screenshot). Same thing can be seen with printing, but I don't have a small test case for it. You can try 'hg clone http://mooedit.sf.net/hg/moo', build it, run, open a big file (so that printing is slow), start printing and open file chooser.
Created attachment 69358 [details] filechooser in gedit
Created attachment 69359 [details] filechooser and printing Screenshot here shows filechooser opened before PrintOperation started generating pages. Once it actually started generating pages, filechooser is working fine.
I can confirm this running Ubuntu edgy on amd64
Ugh. The problem is that you are essentially trying to do multitasking using idle handlers, and they are just not good for that ;) I'm not opposed to making GtkFileSystemUnix use higher-priority idles, but then again GtkFileSystemGnomeVFS would have exactly the same problem. [And then, Gnome-VFS dispatches async callbacks in a normal-priority idle, too!] Would it be feasible to run your print operation in a thread, if you really want it to happen in the background?
(In reply to comment #4) > Ugh. The problem is that you are essentially trying to do multitasking using > idle handlers, and they are just not good for that ;) Yep. > Would it be feasible to run your print operation in a thread, if you really > want it to happen in the background? Absolutely not feasible. Atm it's simple - create a print operation, connect to draw-page, and go print. Adding threads to it is way too hard. It'd be cool perhaps if GtkPrintOperation used threads internally, but it's certainly not a good option for application (imagine setting up progress callbacks).
anything wrong with making the gtkprintoperation use a lower priority than default ?
2006-08-17 Matthias Clasen <mclasen@redhat.com> * gtk/gtkprintoperation.c (print_pages, preview_ready): Queue printing idles at a low priority. (#348289, Yevgen Muntyan)
It might fix the problem with printing, but GtkTextView (calculating lines) and GtkSourceView (syntax highlighting) still block FileChooser. It's unlikely GtkTextView may change its GTK_TEXT_VIEW_PRIORITY_VALIDATE, and GtkSourceView uses the same priority, it says: /* Use the text view validation priority to get * highlighted text even before complete validation of * the buffer. */ So, should GtkFileChooser be fixed to use high priority for one-time things; or is multitasking-in-idle broken, maybe one need to write custom GSource for such things (is it possible?); or... ?
(In reply to comment #8) > So, should GtkFileChooser be fixed to use high priority for one-time things; or definitely, the problem shows up in other places as well: http://mail.gnome.org/archives/gtk-devel-list/2006-August/msg00081.html > is multitasking-in-idle broken, maybe one need to write custom GSource for such > things (is it possible?); or... ? no, multitasking via idlers is exactly what the idle handlers are for. you just need to carefully pick the priority your idler is running at. for not-so-important things, the standard idle priority (G_PRIORITY_DEFAULT_IDLE) is good enough (lower than event handling, resizing, redrawing). for user visible things on a busy CPU, you'd want to use G_PRIORITY_DEFAULT though, which runs round-robin with event processing, and for very important one-shot tasks that just need to be run asyncronously, you might even use G_PRIORITY_HIGH (more important than GUI/input event processing, which is rarely the case). the file system callback definitely falls into the category of needing priority>=G_PRIORITY_DEFAULT though.
(In reply to comment #9) > (In reply to comment #8) > > is multitasking-in-idle broken, maybe one need to write custom GSource for such > > things (is it possible?); or... ? > > no, multitasking via idlers is exactly what the idle handlers are for. you just > need to carefully pick the priority your idler is running at. for > not-so-important things, the standard idle priority (G_PRIORITY_DEFAULT_IDLE) > is good enough (lower than event handling, resizing, redrawing). > for user visible things on a busy CPU, you'd want to use G_PRIORITY_DEFAULT > though, which runs round-robin with event processing, and for very important > one-shot tasks that just need to be run asyncronously, you might even use > G_PRIORITY_HIGH (more important than GUI/input event processing, which is > rarely the case). Obviously, I am most concerned about GtkSourceView syntax highlighting. It's slow enough to qualify as long-running task, but then there is printing, which is a long-running task as well. Now printing lowered its priority, I don't know who wins but obviously only one wins (I doubt it has GTK_TEXT_VIEW_PRIORITY_VALIDATE priority). So the general problem about multitasking-in-idle still exists. It might not be on-topic in this bug report though. I'll try to compose a nice mail to gtk-devel-list.
Paolo, could you comment on why gtksourceview uses GTK_TEXT_VIEW_PRIORITY_VALIDATE?
Shouldn't glib avoid starvation[1] of idle handlers? I.e. call a lower priority handlers less often, but still call them once in a while even when higher-priority handlers keep around. [1] http://en.wikipedia.org/wiki/Resource_starvation
(In reply to comment #12) > Shouldn't glib avoid starvation[1] of idle handlers? I.e. call a lower > priority handlers less often, but still call them once in a while even when > higher-priority handlers keep around. > > [1] http://en.wikipedia.org/wiki/Resource_starvation no, the glib main loop provides you with the behaviour that, if you have two pending handlers at different priorities, you can rely on the handler with the higher priority being executed first. with ever-repeating, pure idle handlers, that will lead to resource starvation, yes. however that's not the intended long-term usage scenario, the idea is that at least one of the following items remedies the situation: - your handlers don't run forever (one-shot being the vast majority); - your handlers are not pure idlers, i.e. you use timeouts or poll-fds that volountarily give up CPU after each execution; - for the rare cases where you have a forever running pure idler (e.g. a number cruncher like in the SETI screensaver), you use the lowest possible priority, so your task runs effectively in the background without interfering with any other work that has to be performed. i would use -G_MININT/2 as maximum priority for such a background task, to leave the range of -G_MININT/2..-G_MININT for piorization of such background tasks.
It is not very related to this bug report, but I think we can alleviate the problem stopping syntax highlighting in GtkSourceBuffer if the associated view is not focused, i.e. we try to highlight the current visible part of the buffer and then give up with the other parts. We used GTK_TEXT_VIEW_PRIORITY_VALIDATE in gtksourceview for the reason written in the comment Muntyan reported. Buffer validation can be a long operation and we want to start highlighting the buffer before the validation is terminated. About the problem of making GtkFileSystemUnix using a higher-priority I am a bit worried by the concerns Federico reported in comment #4 about GtkFileSystemGnomeVFS.
Tim is right here ... the priority system for the GLib main loop is not really intended for the case where you are doing arbitrary amounts of work indefinitely. The intended use case is more for things like: Process all pending mouse events before we start redrawing a widget GTK+ does this by installing the install and resize one-shot idles at a lower priority than the priority of incoming GDK events. Trying to write a full scheduler in gmain.c just doesn't make sense; as you can see from the work that the scheduler in the Linux kernel has gotten over the years, it's a hard job! I don't have even a clue as to how you would begin making the gmain run lower priority idles "some of the time" in any sort of predictable way.
OK. Anyway adding an advanced scheduler would probably break existing code.
I'm tempted to close this as WONTFIX, but I haven't really thought about the "right" priorities for the delivery of file-related notifications. We would have to change gnome-vfs and everything in the pipeline. We can certainly do "file stuff should happen before redrawing" if it makes sense, but I don't think we can coordinate it with other random low-level code like print operations or textview layout.
(In reply to comment #17) > I'm tempted to close this as WONTFIX, but I haven't really thought about the > "right" priorities for the delivery of file-related notifications. We would > have to change gnome-vfs and everything in the pipeline. > > We can certainly do "file stuff should happen before redrawing" if it makes > sense, but I don't think we can coordinate it with other random low-level code > like print operations or textview layout. note that for anything that should appear to be happening "in the background" and not stall GUI updates, you need to use priorities numerically >= GTK_PRIORITY_DEFAULT. if you also don't want to interfere with custom user idlers/timers, GTK_PRIORITY_LOW or GTK_PRIORITY_LOW + 10 would be best.
Removed 2.10.3 taret milestore as the current GTK+ version is 2.22
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.