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>
bb10
Thiago Macieira 2016-01-30 09:48:41 -08:00 committed by Jani Heikkinen
parent e5e9387f9a
commit 46c73be471
2 changed files with 13 additions and 5 deletions

View File

@ -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

View File

@ -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);