Update Apple implementation to cancel the timer before calling the callback

This fixes a crash where the Timer is destroyed as soon as the callback is called, so Timer::Stop can't be safely called.

PiperOrigin-RevId: 521760888
This commit is contained in:
Nick Bourdakos
2023-04-04 07:47:14 -07:00
committed by Copybara-Service
parent 977275f069
commit d6f66237b0
@@ -52,13 +52,17 @@ bool Timer::Create(int delay, int interval, absl::AnyInvocable<void()> callback)
dispatch_get_main_queue());
dispatch_source_set_event_handler(timer_, ^{
// If our interval is `DISPATCH_TIME_FOREVER`, it means we only want the timer to fire once.
// We need to cancel the timer before the callback is called since the `Timer` object may no
// longer exist immediately after invoking the callback.
if (intervalInNanoseconds == DISPATCH_TIME_FOREVER && timer_ != nil) {
dispatch_source_cancel(timer_);
timer_ = nil;
}
if (callback_ != nil) {
callback_();
}
// If our interval is `DISPATCH_TIME_FOREVER`, it means we only want the timer to fire once.
if (intervalInNanoseconds == DISPATCH_TIME_FOREVER) {
Stop();
}
});
dispatch_source_set_timer(timer_, dispatch_time(DISPATCH_TIME_NOW, delayInNanoseconds),