diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/global/qprocessordetection.h | 9 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemwatcher_inotify.cpp | 21 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool.cpp | 79 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool_p.h | 6 | ||||
-rw-r--r-- | src/corelib/tools/qline.cpp | 7 | ||||
-rw-r--r-- | src/corelib/tools/qt_attribution.json | 4 |
7 files changed, 72 insertions, 56 deletions
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index aaa27dff4a..77b3ba36b0 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -94,8 +94,8 @@ ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to auto-detection implemented below. */ -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__) || defined(__ARM64__) -# if defined(__aarch64__) || defined(__ARM64__) +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) +# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) # define Q_PROCESSOR_ARM_64 # define Q_PROCESSOR_WORDSIZE 8 # else @@ -110,7 +110,8 @@ # elif defined(__ARM64_ARCH_8__) \ || defined(__aarch64__) \ || defined(__ARMv8__) \ - || defined(__ARMv8_A__) + || defined(__ARMv8_A__) \ + || defined(_M_ARM64) # define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ @@ -148,7 +149,7 @@ # else # error "ARM architecture too old" # endif -# if defined(__ARMEL__) +# if defined(__ARMEL__) || defined(_M_ARM64) # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # elif defined(__ARMEB__) # define Q_BYTE_ORDER Q_BIG_ENDIAN diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5a5a3a82c6..b2d81066db 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -285,7 +285,7 @@ mtime(const T &statBuffer, int) { return timespecToMSecs(statBuffer.st_mtimespec); } #endif -#ifndef st_mtimensec +#if !defined(st_mtimensec) && !defined(__alpha__) // Xtimensec template <typename T> Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimensec, true), qint64>::type diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 3b7135e582..a5e629b646 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -330,13 +330,24 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path while (it.hasNext()) { QString path = it.next(); int id = pathToID.take(path); - QString x = idToPath.take(id); - if (x.isEmpty() || x != path) + + // Multiple paths could be associated to the same watch descriptor + // when a file is moved and added with the new name. + // So we should find and delete the correct one by using + // both id and path + auto path_range = idToPath.equal_range(id); + auto path_it = std::find(path_range.first, path_range.second, path); + if (path_it == idToPath.end()) continue; - int wd = id < 0 ? -id : id; - // qDebug() << "removing watch for path" << path << "wd" << wd; - inotify_rm_watch(inotifyFd, wd); + const ssize_t num_elements = std::distance(path_range.first, path_range.second); + idToPath.erase(path_it); + + // If there was only one path associated to the given id we should remove the watch + if (num_elements == 1) { + int wd = id < 0 ? -id : id; + inotify_rm_watch(inotifyFd, wd); + } it.remove(); if (id < 0) { diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index ea2c611082..4d2389f699 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -39,7 +39,7 @@ #include "qthreadpool.h" #include "qthreadpool_p.h" -#include "qelapsedtimer.h" +#include "qdeadlinetimer.h" #include <algorithm> @@ -130,11 +130,6 @@ void QThreadPoolThread::run() } } while (true); - if (manager->isExiting) { - registerThreadInactive(); - break; - } - // if too many threads are active, expire this thread bool expired = manager->tooManyThreadsActive(); if (!expired) { @@ -145,6 +140,10 @@ void QThreadPoolThread::run() ++manager->activeThreads; if (manager->waitingThreads.removeOne(this)) expired = true; + if (!manager->allThreads.contains(this)) { + registerThreadInactive(); + break; + } } if (expired) { manager->expiredThreads.enqueue(this); @@ -267,7 +266,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this)); thread->setObjectName(QLatin1String("Thread (pooled)")); Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here) - allThreads.append(thread.data()); + allThreads.insert(thread.data()); ++activeThreads; if (runnable->autoDelete()) @@ -278,49 +277,54 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) /*! \internal - Makes all threads exit, waits for each thread to exit and deletes it. + + Helper function only to be called from waitForDone(int) */ void QThreadPoolPrivate::reset() { - QMutexLocker locker(&mutex); - isExiting = true; - - while (!allThreads.empty()) { - // move the contents of the set out so that we can iterate without the lock - QList<QThreadPoolThread *> allThreadsCopy; - allThreadsCopy.swap(allThreads); - locker.unlock(); + // move the contents of the set out so that we can iterate without the lock + QSet<QThreadPoolThread *> allThreadsCopy; + allThreadsCopy.swap(allThreads); + expiredThreads.clear(); + waitingThreads.clear(); + mutex.unlock(); - for (QThreadPoolThread *thread : qAsConst(allThreadsCopy)) { + for (QThreadPoolThread *thread: qAsConst(allThreadsCopy)) { + if (!thread->isFinished()) { thread->runnableReady.wakeAll(); thread->wait(); - delete thread; } - - locker.relock(); - // repeat until all newly arrived threads have also completed + delete thread; } - waitingThreads.clear(); - expiredThreads.clear(); + mutex.lock(); +} + +/*! + \internal - isExiting = false; + Helper function only to be called from waitForDone(int) +*/ +bool QThreadPoolPrivate::waitForDone(const QDeadlineTimer &timer) +{ + while (!(queue.isEmpty() && activeThreads == 0) && !timer.hasExpired()) + noActiveThreads.wait(&mutex, timer); + + return queue.isEmpty() && activeThreads == 0; } bool QThreadPoolPrivate::waitForDone(int msecs) { QMutexLocker locker(&mutex); - if (msecs < 0) { - while (!(queue.isEmpty() && activeThreads == 0)) - noActiveThreads.wait(locker.mutex()); - } else { - QElapsedTimer timer; - timer.start(); - int t; - while (!(queue.isEmpty() && activeThreads == 0) && - ((t = msecs - timer.elapsed()) > 0)) - noActiveThreads.wait(locker.mutex(), t); - } + QDeadlineTimer timer(msecs); + do { + if (!waitForDone(timer)) + return false; + reset(); + // More threads can be started during reset(), in that case continue + // waiting if we still have time left. + } while ((!queue.isEmpty() || activeThreads) && !timer.hasExpired()); + return queue.isEmpty() && activeThreads == 0; } @@ -686,10 +690,7 @@ void QThreadPool::releaseThread() bool QThreadPool::waitForDone(int msecs) { Q_D(QThreadPool); - bool rc = d->waitForDone(msecs); - if (rc) - d->reset(); - return rc; + return d->waitForDone(msecs); } /*! diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 0e6a00d243..952e02ef20 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -63,6 +63,8 @@ QT_REQUIRE_CONFIG(thread); QT_BEGIN_NAMESPACE +class QDeadlineTimer; + class QueuePage { public: enum { @@ -163,12 +165,13 @@ public: void startThread(QRunnable *runnable = 0); void reset(); bool waitForDone(int msecs); + bool waitForDone(const QDeadlineTimer &timer); void clear(); void stealAndRunRunnable(QRunnable *runnable); void deletePageIfFinished(QueuePage *page); mutable QMutex mutex; - QList<QThreadPoolThread *> allThreads; + QSet<QThreadPoolThread *> allThreads; QQueue<QThreadPoolThread *> waitingThreads; QQueue<QThreadPoolThread *> expiredThreads; QVector<QueuePage*> queue; @@ -179,7 +182,6 @@ public: int reservedThreads = 0; int activeThreads = 0; uint stackSize = 0; - bool isExiting = false; }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 9704a00b85..949f63ea15 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -387,10 +387,9 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) \value UnboundedIntersection The two lines intersect, but not within the range defined by their lengths. This will be the case - if the lines are not parallel. - - intersect() will also return this value if the intersect point is - within the start and end point of only one of the lines. + if the lines are not parallel. intersect() will also return this + value if the intersect point is within the start and end point of + only one of the lines. \value BoundedIntersection The two lines intersect with each other within the start and end points of each line. diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/tools/qt_attribution.json index 5bb95c9f5b..a842d9467b 100644 --- a/src/corelib/tools/qt_attribution.json +++ b/src/corelib/tools/qt_attribution.json @@ -4,12 +4,14 @@ "Name": "Unicode Character Database (UCD)", "QDocModule": "qtcore", "QtUsage": "Qt Core uses data obtained from UCD files for working with characters and strings.", + "Files": "For update, see qtbase/util/unicode/README", "Files": "qunicodetables_p.h qunicodetables.cpp", "Description": "The Unicode Character Database (UCD) is a set of files that define the Unicode character properties and internal mappings.", "Homepage": "https://www.unicode.org/ucd/", - "Version": "10.0.0", + "Version": "Don't use the Unicode standard version; UCD has its own 'Revision' numbers", + "Version": "20", "License": "Unicode License Agreement - Data Files and Software (2016)", "LicenseId": "Unicode-DFS-2016", "LicenseFile": "UNICODE_LICENSE.txt", |