summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2019-11-16 16:02:29 +0200
committerAlex Trotsenko <alex1973tr@gmail.com>2020-03-03 19:44:01 +0200
commit23785face5a01bf63334fd32975718468d5f816e (patch)
treecfdea28f388edfd2c994fe62dc350f191c71be95 /src/corelib
parentb711ee255515440b923a898f65f6afe13d63916f (diff)
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>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp5
3 files changed, 10 insertions, 4 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 8616631603..f2216d4113 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -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));
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index e6620178d8..a482c8b7db 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -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);
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index db5d44b276..0c574e9a4b 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -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;