Windows: Prevent registration of timers in shutdown phase
Do not register new timers after closingDown() has been called. They might call back into QEventDispatcherWin32 after the object has been destructed, leading to crashes on exit. registerSocketNotifier has a similar protection using QCoreApplication::closingDown(). This however does not work in all cases, because QEventDispatcher::closingDown() is called in ~QGuiApplication(), while QCoreApplication::is_app_closing is set in ~QCoreApplication(). In between qt_call_post_routines() is called, which might trigger new timers to be registered. Task-number: QTBUG-42772 Change-Id: I91325fb10e38c117c1cbedfee272d0ab6a5ca8fa Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
parent
52f5bf9cd5
commit
087aa1f3cb
@ -307,8 +307,9 @@ static void resolveTimerAPI()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
|
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
|
||||||
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
|
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
|
||||||
serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0)
|
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
|
||||||
|
wakeUps(0)
|
||||||
{
|
{
|
||||||
resolveTimerAPI();
|
resolveTimerAPI();
|
||||||
}
|
}
|
||||||
@ -931,6 +932,11 @@ void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerTy
|
|||||||
|
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(QEventDispatcherWin32);
|
||||||
|
|
||||||
|
// exiting ... do not register new timers
|
||||||
|
// (QCoreApplication::closingDown() is set too late to be used here)
|
||||||
|
if (d->closingDown)
|
||||||
|
return;
|
||||||
|
|
||||||
WinTimerInfo *t = new WinTimerInfo;
|
WinTimerInfo *t = new WinTimerInfo;
|
||||||
t->dispatcher = this;
|
t->dispatcher = this;
|
||||||
t->timerId = timerId;
|
t->timerId = timerId;
|
||||||
@ -1155,6 +1161,8 @@ void QEventDispatcherWin32::closingDown()
|
|||||||
d->timerVec.clear();
|
d->timerVec.clear();
|
||||||
d->timerDict.clear();
|
d->timerDict.clear();
|
||||||
|
|
||||||
|
d->closingDown = true;
|
||||||
|
|
||||||
uninstallMessageHook();
|
uninstallMessageHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +147,7 @@ public:
|
|||||||
DWORD threadId;
|
DWORD threadId;
|
||||||
|
|
||||||
bool interrupt;
|
bool interrupt;
|
||||||
|
bool closingDown;
|
||||||
|
|
||||||
// internal window handle used for socketnotifiers/timers/etc
|
// internal window handle used for socketnotifiers/timers/etc
|
||||||
HWND internalHwnd;
|
HWND internalHwnd;
|
||||||
|
Loading…
Reference in New Issue
Block a user