You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This code has a subtle bug: if syscall returns EINTRTEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER will retry syscall AS IS[ without adjusting timeout. This meant that each EINTR would effectively delay expiration of the timeout by millis.
This bug went unnoticed for a while because EINTR does not occur all that often in practice. However it was recently revealed due to interaction with Android's Cached Apps Freezer, which is implemented on top of cgroups freezer. When Android freezes and then subsequently thaws an app a pending epoll_wait completes with EINTR. This means that freezing an app which has a timer with large delay and then thawing it would effectively reset the timer, introducing delay affecting that timer and all other timers waiting in the queue after this timer (assuming that there is no other event handler activity in the application).
This was observed in the wild on an internal Flutter application where a Timer created by a UI interaction sometimes would fire with a huge delay causing UI to become stuck (b/311165013).
The Linux implementation of the event handler was migrated to timerfd 10 years ago (9a8edb6) but the same change was never ported to eventhandler_android.cc.
In reality there is no strong reason for eventhandler_android.cc to exist in the first place. It is almost line by line copy of eventhandler_linux.cc which slightly drifted away from Linux implementation over time. So I am going to fix this bug by removing all Android specific files in runtime/bin and use Linux implementation instead (with a couple of #ifdef-s where OSes differ in a meaningful way).
Android implementation of timers was using
epoll_wait
timeout to drive timer wake ups:This code has a subtle bug: if syscall returns
EINTR
TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER
will retry syscall AS IS[ without adjusting timeout. This meant that eachEINTR
would effectively delay expiration of the timeout bymillis
.This bug went unnoticed for a while because
EINTR
does not occur all that often in practice. However it was recently revealed due to interaction with Android's Cached Apps Freezer, which is implemented on top of cgroups freezer. When Android freezes and then subsequently thaws an app a pendingepoll_wait
completes withEINTR
. This means that freezing an app which has a timer with large delay and then thawing it would effectively reset the timer, introducing delay affecting that timer and all other timers waiting in the queue after this timer (assuming that there is no other event handler activity in the application).This was observed in the wild on an internal Flutter application where a
Timer
created by a UI interaction sometimes would fire with a huge delay causing UI to become stuck (b/311165013).The Linux implementation of the event handler was migrated to
timerfd
10 years ago (9a8edb6) but the same change was never ported toeventhandler_android.cc
.In reality there is no strong reason for eventhandler_android.cc to exist in the first place. It is almost line by line copy of eventhandler_linux.cc which slightly drifted away from Linux implementation over time. So I am going to fix this bug by removing all Android specific files in
runtime/bin
and use Linux implementation instead (with a couple of#ifdef
-s where OSes differ in a meaningful way).CL: https://dart-review.googlesource.com/c/sdk/+/350923
The text was updated successfully, but these errors were encountered: