GNOME Bugzilla – Bug 610830
low priority task never executed if a high priority task is using all the CPU
Last modified: 2010-03-17 12:19:42 UTC
Created attachment 154505 [details] test case If the main loop has a high priority timeout function taking all CPU while it's running and a low priority function, the low priority function doesn't seem to get called, ever. The attached test, when executed will always print "done", I couldn't see it print "low priority".
Yes, GLib should sometimes run lower-prio tasks too, even if there are still higher prio tasks pending. Starving the lower prio tasks is definitely not a good idea.
I don't think I agree. And the main loop docs clearly state that this is going to happen: "Events from high priority sources are always processed before events from lower priority sources." The reason is quite simple: If you add some idle task it should be assumed it really is an _idle_ task, i.e. something that can be executed whenever there is time available and does not need to be executed at all. I'd imagine Gnumeric recomputing all cells, VMs running their GC, Abiword relayouting the whole document or the treeview recomputing sizes for invisible rows in an idle handler and those should not be executed while something important happens (like you pasting a lot of text into Gnumeric or Abiword). That said, in a lot of cases it is useful to have tasks that increase their priority over time. An example here is doing repaints while processing script timeouts in a browser: You don't want to redraw after every timeout (that roughly gets you 100 redraws/sec) but you want to redraw from time to time so users actually see stuff happening. Currently one would need to register N different timeout sources with increasing priority and delay like so: g_timeout_add_full (GDK_PRIORITY_REDRAW, 0, do_redraw, data, NULL); g_timeout_add_full (G_PRIORITY_DEFAULT, 500, do_redraw, data, NULL); g_timeout_add_full (G_PRIORITY_HIGH, 2000, do_redraw, data, NULL); That would ensure that you likely get a redraw after 0.5s and definitely get one after 2s. So I think it would be nice if we had an easy way to do achieve this. Not sure how to implement it though, I think the main loop code doesn't allow this easily.
Paolo Porelli just mentioned on IRC that there's probably a lot of code out there that implicitly relies on the ordering of tasks by priorities where executing them in a different order would cause SEGVs. So Philippe's request is definitely a WONTFIX.
(In reply to comment #2) > I don't think I agree. And the main loop docs clearly state that this is going > to happen: "Events from high priority sources are always processed before > events from lower priority sources." > The reason is quite simple: If you add some idle task it should be assumed it > really is an _idle_ task, i.e. something that can be executed whenever there is > time available and does not need to be executed at all. I'd imagine Gnumeric > recomputing all cells, VMs running their GC, Abiword relayouting the whole > document or the treeview recomputing sizes for invisible rows in an idle > handler and those should not be executed while something important happens > (like you pasting a lot of text into Gnumeric or Abiword). I disagree with "does not need to be executed". The documentation makes it clear that high priority tasks will take precedence but that doesn't imply that idles are dropped randomly. A lot of code assumes that g_idle means "run when there is time, defer it if you will, but run it", not "run if you like".
(In reply to comment #3) > Paolo Porelli just mentioned on IRC that there's probably a lot of code out > there that implicitly relies on the ordering of tasks by priorities where > executing them in a different order would cause SEGVs. > So Philippe's request is definitely a WONTFIX. I agree with this - you can debate whether the way that the main loop is set up is right or not, but this sort of change in the scheduling algorithm is going to break things, quite possibly in incredibly subtle ways.
So I guess I'll WONTFIX this. It's intended behavior.