[Webkit-unassigned] [Bug 23865] Safari can be frozen by rapidly adding timers

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Feb 10 20:28:16 PST 2009


------- Comment #5 from dimich at chromium.org  2009-02-10 20:28 PDT -------
Sorry, I should have done more experimenting before floating a theory above.

The code Alexey used to file this bug can generate a lot of timers. Even though
each of the invocations only creates 2 more and exits, the overall time in
ThreadTimers::sharedTimerFiredInternal() grows exponentially. I've added
printing of timer count and overall time spent there, here is the result:
** 2 timers, took 0.4 ms
** 10 timers, took 0.6 ms
** 14 timers, took 0.8 ms
** 16 timers, took 1.2 ms
** 26 timers, took 1.6 ms
** 31 timers, took 1.9 ms
** 20 timers, took 1.5 ms
** 22 timers, took 1.4 ms
** 21 timers, took 1.4 ms
** 45 timers, took 2.9 ms
** 81 timers, took 5.5 ms
** 145 timers, took 10.0 ms
** 285 timers, took 19.8 ms
** 546 timers, took 38.2 ms
** 1086 timers, took 78.6 ms
** 2159 timers, took 152.8 ms
** 4295 timers, took 301.6 ms
** 8611 timers, took 625.8 ms
** 17236 timers, took 1254.7 ms
** 34440 timers, took 2546.1 ms
** 69056 timers, took 5250.1 ms
** 138270 timers, took 10695.5 ms
** 276547 timers, took 22173.0 ms

Each time the shared timer is fired, we go through collection of all timers and
find out that they all are to be fired - so we loop through all and it takes
ever-increasing time. As you can see, very quickly the time spent without
returning to the run loop grows into seconds - so the beach ball appears and
input events becomes very slow. It seems the input events such as mouse
moves/clicks are accumulated and then dispatched in small portions between
timer firing. So the user input would need several 'turns' with the timer to
move the pointer/highlight the target/process the click. With growing interval
between 'turns' it becomes nearly impossible.

Note that timeout mechanism that measures if a piece of script runs too long
and aborts it if so (preventing "while(true) {}" from freezing UI) would not
help here because each particular JS callback is short. It seems that if we
need to fix this, we need to measure how long we are executing timers and break
out of the loop with posting another timer when we run them for too long.

I'll have a patch soon.

Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

More information about the webkit-unassigned mailing list