High CPU on idle application, on Windows, signal_timeout
Submitted by mat..@..ch.edu
Link to original bug (#675695)
Description
This was originally posted under glibm as bug 675485, but I have since traced the problem into glib's gmain.c and gpoll.c, so it belongs here. When built on mingw on XP SP3 (32 bit) the attached example runs at 17% CPU even when minimized.
The problem is that when Glib::signal_timeout().connect is used, or equivalently,
source = g_timeout_source_new(50);
g_source_set_callback(source,
(GSourceFunc)slot_timeout,
NULL,
NULL);
g_source_attach(source,
NULL);
the polling method in glib goes nuts for the test program. (Or any program, this was initially discovered on Inkscape. https://bugs.launchpad.net/inkscape/+bug/871968 ) Removing the signal_timeout from the test program lets it run normally (no idle CPU use).
For the simplest case, the test application window minimized (so no keyboard or mouse input):
What it should do: timeout every 50 msecs, run the slot_timeout function, and then wait another 50 msecs.
What it does: timeout once initially at 50 msecs, run the slot function, then set a timeout of 4 msecs or 0 msecs, both of which time out instantly. Eventually it gets back to 50 msec, which is probably why it only uses 17% of CPU and not 100%.
If the timeout is set very long, say 200 msecs, then it does what it is supposed to do, without any of the timeout confusion. It just does a succession of 0.2 sec waits and runs of slot_timeout(). It starts to become a problem at around 100 msecs and becomes pathological for timeouts <20 ms. (Too short for the hardware, probably.)
The same code run under wine (32 bit, on Ubuntu) behaves exactly the same way.
Near as I can tell the problem is in g_main_context_prepare, which comes up with these other timeout values. My guess is that its original purpose was to handle a case like:
MsgWaitForMultipleObjectsEx with wait of 100 msec another event happens set wait for next MsgWaitForMultipleObjectsEx for remainder of 100 msec
but it is making a total hash of the situation where there is no other event and the initial timeout is on the order of 50 msec.
Version: 2.28.x