From ab91ac09924f7e356e4d2b8cf40c89a3c12011bb Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 16 Mar 2020 13:29:22 +0100 Subject: Don't store iterators on QHash while erasing QHash::erase() in the new QHash will invalidate all iterators pointing into the hash. Change-Id: Ia54e8485a947cd7274f832c7c8c624d0aaded4ba Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemwatcher_polling.cpp | 25 ++++++++------- src/corelib/io/qfilesystemwatcher_win.cpp | 37 +++++++++++----------- .../input/evdevtouch/qevdevtouchhandler.cpp | 20 ++++++------ 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_polling.cpp b/src/corelib/io/qfilesystemwatcher_polling.cpp index e07b02f7c2..6920eab258 100644 --- a/src/corelib/io/qfilesystemwatcher_polling.cpp +++ b/src/corelib/io/qfilesystemwatcher_polling.cpp @@ -111,37 +111,40 @@ QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &path void QPollingFileSystemWatcherEngine::timeout() { for (auto it = files.begin(), end = files.end(); it != end; /*erasing*/) { - auto x = it++; - QString path = x.key(); + QString path = it.key(); QFileInfo fi(path); if (!fi.exists()) { - files.erase(x); + it = files.erase(it); emit fileChanged(path, true); - } else if (x.value() != fi) { - x.value() = fi; + continue; + } else if (it.value() != fi) { + it.value() = fi; emit fileChanged(path, false); } + ++it; } for (auto it = directories.begin(), end = directories.end(); it != end; /*erasing*/) { - auto x = it++; - QString path = x.key(); + QString path = it.key(); QFileInfo fi(path); if (!path.endsWith(QLatin1Char('/'))) fi = QFileInfo(path + QLatin1Char('/')); if (!fi.exists()) { - directories.erase(x); + it = directories.erase(it); emit directoryChanged(path, true); - } else if (x.value() != fi) { + continue; + } else if (it.value() != fi) { fi.refresh(); if (!fi.exists()) { - directories.erase(x); + it = directories.erase(it); emit directoryChanged(path, true); + continue; } else { - x.value() = fi; + it.value() = fi; emit directoryChanged(path, false); } } + ++it; } } diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index f955e3b53a..2f0a209b76 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -697,21 +697,20 @@ void QWindowsFileSystemWatcherEngineThread::run() qErrnoWarning(error, "%ls", qUtf16Printable(msgFindNextFailed(h))); } - for (auto it = h.begin(), end = h.end(); it != end; /*erasing*/ ) { - auto x = it++; - QString absolutePath = x.value().absolutePath; - QFileInfo fileInfo(x.value().path); - DEBUG() << "checking" << x.key(); + for (auto it = h.begin(); it != h.end(); /*erasing*/ ) { + QString absolutePath = it.value().absolutePath; + QFileInfo fileInfo(it.value().path); + DEBUG() << "checking" << it.key(); // i'm not completely sure the fileInfo.exist() check will ever work... see QTBUG-2331 // ..however, I'm not completely sure enough to remove it. if (fakeRemove || !fileInfo.exists()) { - DEBUG() << x.key() << "removed!"; - if (x.value().isDir) - emit directoryChanged(x.value().path, true); + DEBUG() << it.key() << "removed!"; + if (it.value().isDir) + emit directoryChanged(it.value().path, true); else - emit fileChanged(x.value().path, true); - h.erase(x); + emit fileChanged(it.value().path, true); + it = h.erase(it); // close the notification handle if the directory has been removed if (h.isEmpty()) { @@ -726,15 +725,17 @@ void QWindowsFileSystemWatcherEngineThread::run() // h is now invalid break; } - } else if (x.value().isDir) { - DEBUG() << x.key() << "directory changed!"; - emit directoryChanged(x.value().path, false); - x.value() = fileInfo; - } else if (x.value() != fileInfo) { - DEBUG() << x.key() << "file changed!"; - emit fileChanged(x.value().path, false); - x.value() = fileInfo; + continue; + } else if (it.value().isDir) { + DEBUG() << it.key() << "directory changed!"; + emit directoryChanged(it.value().path, false); + it.value() = fileInfo; + } else if (it.value() != fileInfo) { + DEBUG() << it.key() << "file changed!"; + emit fileChanged(it.value().path, false); + it.value() = fileInfo; } + ++it; } } } else { diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 78728ef4ce..13829c040e 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -580,9 +580,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) Qt::TouchPointStates combinedStates; bool hasPressure = false; - for (auto i = m_contacts.begin(), end = m_contacts.end(); i != end; /*erasing*/) { - auto it = i++; - + for (auto it = m_contacts.begin(), end = m_contacts.end(); it != end; /*erasing*/) { Contact &contact(it.value()); if (!contact.state) @@ -605,7 +603,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) // Avoid reporting a contact in released state more than once. if (!m_typeB && contact.state == Qt::TouchPointReleased && !m_lastContacts.contains(key)) { - m_contacts.erase(it); + it = m_contacts.erase(it); continue; } @@ -613,6 +611,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) hasPressure = true; addTouchPoint(contact, &combinedStates); + ++it; } // Now look for contacts that have disappeared since the last sync. @@ -633,22 +632,23 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) } // Remove contacts that have just been reported as released. - for (auto i = m_contacts.begin(), end = m_contacts.end(); i != end; /*erasing*/) { - auto it = i++; - + for (auto it = m_contacts.begin(), end = m_contacts.end(); it != end; /*erasing*/) { Contact &contact(it.value()); if (!contact.state) continue; if (contact.state == Qt::TouchPointReleased) { - if (m_typeB) + if (m_typeB) { contact.state = static_cast(0); - else - m_contacts.erase(it); + } else { + it = m_contacts.erase(it); + continue; + } } else { contact.state = Qt::TouchPointStationary; } + ++it; } m_lastContacts = m_contacts; -- cgit v1.2.3