I’m using juce 1.51 to build an app on Mac (Leopard and Snow Leopard) and Windows (XP, Vista, and 7). I’ve only tested the Timer with top-of-tree (as of 22:14 GMT today) and 1.51 on Snow Leopard, but looking at the code, I’m 99% sure the same is true on all platforms in both versions.
If your system has been up for more than 2^32 millisecs (just over 7 weeks), Timer objects stop firing for running apps. For a newly-launched app, the first Timer you register will fire once, but that’s it.
The root problem is that Time::getMillisecondCounter() is documented to return a monotonically increasing value of millis since system startup in a uint32, which is impossible. After 2^32 millisecs of uptime, the counter has to either roll over (thereby breaking monotonicity) or peg at UINT_MAX (breaking “accurate to within a few millisecs”). Stepping through the Time code in the debugger may actually change the behavior (by affecting the 1000ms difference check), but it doesn’t really matter; there’s no way it can do what it’s documented to do–and, either way, Timer::run() will never fire any timers. Each time through the loop, now <= lastTime, so it waits 2ms and continues the loop.
I think the Timer problem can be fixed entirely within Timer::run. I’ll try it locally and submit a patch, if it’s as simple as it should be.
As for the root problem, the simplest fix might be to explicitly make it roll over, and change the documentation to explain the problem (c.f. timeGetTime on MSDN), and of course make sure to fix anything other than Timer that relies on it. (Also, I haven’t looked through the rest of the API to see if the same problem exists in other functions, but if so, they’d need to be fixed the same way.)
Other options off the top of my head include switching getMillisecondCounter to return a uint64 or adding a parallel getMillisecondCounter64 call (which is no fun to implement on top of timeGetTime–you might want to look at reading the 64-bit value directly out of the system shared memory page…), or counting millis since process launch instead of system start (which still has a 7-day rollover problem, but fewer people would be affected, and the workaround isn’t as bad as “reboot your computer”), and/or adding an explicit “reset counter” call that could be used for app-level workarounds.