Priority: P2: Important
Affects Version/s: 5.15.2, 6.1.2
Fix Version/s: None
Component/s: Core: Event loop
For some time I receive a lot of crash reports from qt_fast_timer_proc, but didn't see such crashes on my environment.
Then I tried reason about the code. And it looks like there is a race condition in high precision timer management on Windows.
On some thread QEventDispatcherWin32Private::registerTimer is called, which calls timeSetEvent with WinTimerInfo* raw pointer as user data for the callback qt_fast_timer_proc. The callback will be invoked on a separate worker thread by the system.
On the same dispatcher thread at any time QEventDispatcherWin32Private::unregisterTimer may be called. It calls timeKillEvent and then deletes WinTimerInfo.
To guard agains the race condition TIME_KILL_SYNCHRONOUS flag is used in timeSetEvent. This flag promises that after the return from timeKillEvent the callback of that timer (with that user data) won't be invoked.
The problem is - this can't guard against the race. The callback may have already started on a separate worker thread (but didn't finish or even do anything yet). At that moment calling unregisterTimer will lead to deleted information being read in qt_fast_timer_proc, which assumes that WinTimerInfo somehow outlives the whole callback execution.
Looks like it can't be done safely without mutex locks.