QEventDispatcherWin32: unregister event notifiers on close
When QEventDispatcherWin32::closingDown() is called, threadData->eventDispatcher is already nullptr and the application will no longer process the events. Thus, just as it works for socket notifiers and timers, it makes sense to disable all active event notifiers at this point. Otherwise, it seems possible that an object in signalled state can provoke a data race in the notifier's callback on 'edp' pointer, if QWin32EventDispatcher destructor is running simultaneously. Task-number: QTBUG-64152 Task-number: QTBUG-70214 Change-Id: I6e77f3eeca1b0ea639021e73b86798cba0200ebf Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
b711ee2555
commit
23785face5
@ -884,7 +884,11 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
doUnregisterEventNotifier(notifier);
|
||||
}
|
||||
|
||||
void QEventDispatcherWin32::doUnregisterEventNotifier(QWinEventNotifier *notifier)
|
||||
{
|
||||
Q_D(QEventDispatcherWin32);
|
||||
|
||||
int i = d->winEventNotifierList.indexOf(notifier);
|
||||
@ -996,6 +1000,10 @@ void QEventDispatcherWin32::closingDown()
|
||||
doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj);
|
||||
Q_ASSERT(d->active_fd.isEmpty());
|
||||
|
||||
// clean up any eventnotifiers
|
||||
while (!d->winEventNotifierList.isEmpty())
|
||||
doUnregisterEventNotifier(d->winEventNotifierList.first());
|
||||
|
||||
// clean up any timers
|
||||
for (int i = 0; i < d->timerVec.count(); ++i)
|
||||
d->unregisterTimer(d->timerVec.at(i));
|
||||
|
@ -110,6 +110,7 @@ protected:
|
||||
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
|
||||
virtual void sendPostedEvents();
|
||||
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
|
||||
void doUnregisterEventNotifier(QWinEventNotifier *notifier);
|
||||
|
||||
private:
|
||||
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
||||
|
@ -198,11 +198,8 @@ void QWinEventNotifier::setEnabled(bool enable)
|
||||
d->enabled = enable;
|
||||
|
||||
QAbstractEventDispatcher *eventDispatcher = d->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
|
||||
if (!eventDispatcher) { // perhaps application is shutting down
|
||||
if (!enable && d->waitHandle != nullptr)
|
||||
d->unregisterWaitObject();
|
||||
if (!eventDispatcher) // perhaps application is shutting down
|
||||
return;
|
||||
}
|
||||
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
|
||||
qWarning("QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread");
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user