diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2016-01-30 09:48:41 -0800 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@theqtcompany.com> | 2016-02-02 19:23:28 +0000 |
commit | 46c73be4710a6aa1be84a19151f73d87413a52b4 (patch) | |
tree | db7ff5b4ce441bbceb285e9ba2694220174587d1 /src | |
parent | e5e9387f9a4070a250a6e806ede37453d5368c69 (diff) |
Fix livelock at application exit if threads were running
This only happened in debug mode, though, because in release mode the
warning wasn't printed and the socket notifier was removed. In debug
mode, this loop in closingDown() never exited:
while (!d->sn_read.isEmpty())
unregisterSocketNotifier((*(d->sn_read.begin()))->obj);
[ChangeLog][QtCore][QThread] Fixed a bug that would cause debug-mode
applications to live lock on exit if they had a global static containing
a QThread that wasn't properly exited.
Task-number: QTBUG-49870
Change-Id: I7a9e11d7b64a4cc78e24ffff142e457a4540d6b6
Reviewed-by: Mat Sutcliffe <oktal3700@gmail.com>
Reviewed-by: Roland Winklmeier <Roland.M.Winklmeier@gmail.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 17 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win_p.h | 1 |
2 files changed, 13 insertions, 5 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 1a14500bd4..b3df139743 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -935,9 +935,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); - int sockfd = notifier->socket(); - int type = notifier->type(); #ifndef QT_NO_DEBUG + int sockfd = notifier->socket(); if (sockfd < 0) { qWarning("QSocketNotifier: Internal error"); return; @@ -946,8 +945,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) return; } #endif + doUnregisterSocketNotifier(notifier); +} +void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier) +{ Q_D(QEventDispatcherWin32); + int type = notifier->type(); + int sockfd = notifier->socket(); + Q_ASSERT(sockfd >= 0); + QSFDict::iterator it = d->active_fd.find(sockfd); if (it != d->active_fd.end()) { QSockFd &sd = it.value(); @@ -1203,11 +1210,11 @@ void QEventDispatcherWin32::closingDown() // clean up any socketnotifiers while (!d->sn_read.isEmpty()) - unregisterSocketNotifier((*(d->sn_read.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj); while (!d->sn_write.isEmpty()) - unregisterSocketNotifier((*(d->sn_write.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj); while (!d->sn_except.isEmpty()) - unregisterSocketNotifier((*(d->sn_except.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj); Q_ASSERT(d->active_fd.isEmpty()); // clean up any timers diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 9a53e06730..222562dfce 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -103,6 +103,7 @@ public: protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); virtual void sendPostedEvents(); + void doUnregisterSocketNotifier(QSocketNotifier *notifier); private: friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); |