diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-24 10:37:17 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-10-24 13:40:55 +0200 |
commit | fa9d12f4a20d618caedc77880459fa1af75fd50d (patch) | |
tree | 11bd3cb4541afb924b3ee17f867133e71eb0e090 /src/corelib | |
parent | 895cb4681ee78caaf9b99c88390a74ff1d79ae61 (diff) | |
parent | f174d31667dca184439f520b9624a1471d9556a6 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts:
src/plugins/platforms/windows/qwindowsmousehandler.cpp
src/plugins/platforms/xcb/qxcbimage.cpp
tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
tests/manual/qtabletevent/regular_widgets/main.cpp
Done-with: Friedemann Kleint<Friedemann.Kleint@qt.io>
Done-with: MÃ¥rten Nordheim<marten.nordheim@qt.io>
Change-Id: I5b2499513a92c590ed0756f7d2e93c35a64b7f30
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/corelib.pro | 2 | ||||
-rw-r--r-- | src/corelib/global/global.pri | 23 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 4 | ||||
-rw-r--r-- | src/corelib/global/qrandom.cpp | 8 | ||||
-rw-r--r-- | src/corelib/global/qrandom.h | 12 | ||||
-rw-r--r-- | src/corelib/global/qt_windows.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 3 | ||||
-rw-r--r-- | src/corelib/io/qloggingcategory.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 31 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreevent.cpp | 8 | ||||
-rw-r--r-- | src/corelib/thread/qmutex.h | 2 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool.cpp | 87 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool_p.h | 84 |
13 files changed, 210 insertions, 66 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 3ab7794f2e..4d67e5837f 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -48,8 +48,6 @@ win32 { mingw { # otherwise mingw headers do not declare common functions like putenv CONFIG -= strict_c++ - # Override MinGW's definition in _mingw.h - DEFINES += WINVER=0x600 _WIN32_WINNT=0x0600 } LIBS_PRIVATE += -lws2_32 !winrt { diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 78b37755a4..7c31df4d6a 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -99,16 +99,13 @@ gcc:ltcg { SOURCES += $$VERSIONTAGGING_SOURCES } -# On AARCH64 the fp16 extension is mandatory, so we don't need the conversion tables. -!contains(QT_ARCH, "arm64") { - QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h - - qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) - - qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} - qfloat16_tables.output = global/qfloat16tables.cpp - qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES - qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE - qfloat16_tables.variable_out = SOURCES - QMAKE_EXTRA_COMPILERS += qfloat16_tables -} +QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h + +qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) + +qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} +qfloat16_tables.output = global/qfloat16tables.cpp +qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES +qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE +qfloat16_tables.variable_out = SOURCES +QMAKE_EXTRA_COMPILERS += qfloat16_tables diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f2f807e1d9..36b7560398 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4296,6 +4296,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qDebug(const char *message, ...) \relates <QtGlobal> + \threadsafe Calls the message handler with the debug message \a message. If no message handler has been installed, the message is printed to @@ -4332,6 +4333,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qInfo(const char *message, ...) \relates <QtGlobal> + \threadsafe \since 5.5 Calls the message handler with the informational message \a message. If no @@ -4369,6 +4371,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qWarning(const char *message, ...) \relates <QtGlobal> + \threadsafe Calls the message handler with the warning message \a message. If no message handler has been installed, the message is printed to @@ -4406,6 +4409,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qCritical(const char *message, ...) \relates <QtGlobal> + \threadsafe Calls the message handler with the critical message \a message. If no message handler has been installed, the message is printed to diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index d77ec8075a..9abb9ece7f 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -154,15 +154,19 @@ class SystemRandom { static QBasicAtomicInt s_fdp1; // "file descriptor plus 1" static int openDevice(); +#ifdef Q_CC_GNU + // If it's not GCC or GCC-like, then we'll leak the file descriptor + __attribute__((destructor)) +#endif + static void closeDevice(); SystemRandom() {} - ~SystemRandom(); public: enum { EfficientBufferFill = true }; static qssize_t fillBuffer(void *buffer, qssize_t count); }; QBasicAtomicInt SystemRandom::s_fdp1 = Q_BASIC_ATOMIC_INITIALIZER(0); -SystemRandom::~SystemRandom() +void SystemRandom::closeDevice() { int fd = s_fdp1.loadAcquire() - 1; if (fd >= 0) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index 7f96cd6749..2259f2657a 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -62,8 +62,16 @@ public: static Q_CORE_EXPORT quint64 generate64(); static double generateDouble() { - // use get64() to get enough bits - return double(generate64()) / ((std::numeric_limits<quint64>::max)() + double(1.0)); + // IEEE 754 double precision has: + // 1 bit sign + // 10 bits exponent + // 53 bits mantissa + // In order for our result to be normalized in the range [0, 1), we + // need exactly 53 bits of random data. Use generate64() to get enough. + quint64 x = generate64(); + quint64 limit = Q_UINT64_C(1) << std::numeric_limits<double>::digits; + x >>= std::numeric_limits<quint64>::digits - std::numeric_limits<double>::digits; + return double(x) / double(limit); } static qreal bounded(qreal sup) diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index bc48104edc..67ba27f072 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -48,10 +48,10 @@ #if defined(Q_CC_MINGW) // mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation # ifndef WINVER -# define WINVER 0x600 +# define WINVER 0x601 # endif # ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x600 +# define _WIN32_WINNT 0x601 # endif # ifndef NTDDI_VERSION # define NTDDI_VERSION 0x06000000 diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 35ddb41215..944ca232ee 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -595,6 +595,9 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) params.dwSize = sizeof(params); params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; + params.dwSecurityQosFlags = SECURITY_ANONYMOUS; + params.lpSecurityAttributes = NULL; + params.hTemplateFile = NULL; const HANDLE handle = CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), 0, FILE_SHARE_READ, OPEN_EXISTING, ¶ms); diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 4256d4b6e1..b029274329 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -445,6 +445,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCDebug(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for debug messages in the logging category @@ -469,6 +470,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCDebug(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a debug message \a message in the logging category \a category. @@ -490,6 +492,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCInfo(category) \relates QLoggingCategory + \threadsafe \since 5.5 Returns an output stream for informational messages in the logging category @@ -514,6 +517,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCInfo(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.5 Logs an informational message \a message in the logging category \a category. @@ -535,6 +539,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCWarning(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for warning messages in the logging category @@ -559,6 +564,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCWarning(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a warning message \a message in the logging category \a category. @@ -580,6 +586,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCCritical(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for critical messages in the logging category @@ -604,6 +611,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCCritical(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a critical message \a message in the logging category \a category. diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index ac694a464a..a499dc2d30 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -499,9 +499,10 @@ public: InvalidFragmentError = Fragment << 8, - // the following two cases are only possible in combination - // with presence/absence of the authority and scheme. See validityError(). + // the following three cases are only possible in combination with + // presence/absence of the path, authority and scheme. See validityError(). AuthorityPresentAndPathIsRelative = Authority << 8 | Path << 8 | 0x10000, + AuthorityAbsentAndPathIsDoubleSlash, RelativeUrlPathContainsColonBeforeSlash = Scheme << 8 | Authority << 8 | Path << 8 | 0x10000, NoError = 0 @@ -1627,19 +1628,32 @@ inline QUrlPrivate::ErrorCode QUrlPrivate::validityError(QString *source, int *p return error->code; } - // There are two more cases of invalid URLs that QUrl recognizes and they + // There are three more cases of invalid URLs that QUrl recognizes and they // are only possible with constructed URLs (setXXX methods), not with // parsing. Therefore, they are tested here. // - // The two cases are a non-empty path that doesn't start with a slash and: + // Two cases are a non-empty path that doesn't start with a slash and: // - with an authority // - without an authority, without scheme but the path with a colon before // the first slash + // The third case is an empty authority and a non-empty path that starts + // with "//". // Those cases are considered invalid because toString() would produce a URL // that wouldn't be parsed back to the same QUrl. - if (path.isEmpty() || path.at(0) == QLatin1Char('/')) + if (path.isEmpty()) return NoError; + if (path.at(0) == QLatin1Char('/')) { + if (sectionIsPresent & QUrlPrivate::Authority || port != -1 || + path.length() == 1 || path.at(1) != QLatin1Char('/')) + return NoError; + if (source) { + *source = path; + *position = 0; + } + return AuthorityAbsentAndPathIsDoubleSlash; + } + if (sectionIsPresent & QUrlPrivate::Host) { if (source) { *source = path; @@ -2514,10 +2528,7 @@ void QUrl::setPath(const QString &path, ParsingMode mode) mode = TolerantMode; } - int from = 0; - while (from < data.length() - 2 && data.midRef(from, 2) == QLatin1String("//")) - ++from; - d->setPath(data, from, data.length()); + d->setPath(data, 0, data.length()); // optimized out, since there is no path delimiter // if (path.isNull()) @@ -3989,6 +4000,8 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err case QUrlPrivate::AuthorityPresentAndPathIsRelative: return QStringLiteral("Path component is relative and authority is present"); + case QUrlPrivate::AuthorityAbsentAndPathIsDoubleSlash: + return QStringLiteral("Path component starts with '//' and authority is absent"); case QUrlPrivate::RelativeUrlPathContainsColonBeforeSlash: return QStringLiteral("Relative URL's path component contains ':' before any '/'"); } diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index e90cd842ab..1e6b328c75 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -170,10 +170,10 @@ QT_BEGIN_NAMESPACE \value LeaveEditFocus An editor widget loses focus for editing. QT_KEYPAD_NAVIGATION must be defined. \value LeaveWhatsThisMode Send to toplevel widgets when the application leaves "What's This?" mode. \value LocaleChange The system locale has changed. - \value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area. - \value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area. - \value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area. - \value NonClientAreaMouseMove A mouse move occurred outside the client area. + \value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseMove A mouse move occurred outside the client area (QMouseEvent). \value MacSizeChange The user changed his widget sizes (\macos only). \value MetaCall An asynchronous method invocation via QMetaObject::invokeMethod(). \value ModifiedChange Widgets modification state has been changed. diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index f40dd3c814..541f6af546 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -251,7 +251,7 @@ class Q_CORE_EXPORT QMutex public: enum RecursionMode { NonRecursive, Recursive }; - inline explicit QMutex(RecursionMode mode = NonRecursive) Q_DECL_NOTHROW { Q_UNUSED(mode); } + inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) Q_DECL_NOTHROW { } inline void lock() Q_DECL_NOTHROW {} inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; } diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index fd5a1106a0..157cbeaf4d 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -73,7 +73,7 @@ public: \internal */ QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager) - :manager(manager), runnable(0) + :manager(manager), runnable(nullptr) { setStackSize(manager->stackSize); } @@ -86,7 +86,7 @@ void QThreadPoolThread::run() QMutexLocker locker(&manager->mutex); for(;;) { QRunnable *r = runnable; - runnable = 0; + runnable = nullptr; do { if (r) { @@ -118,8 +118,19 @@ void QThreadPoolThread::run() if (manager->tooManyThreadsActive()) break; - r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0; - } while (r != 0); + if (manager->queue.isEmpty()) { + r = nullptr; + break; + } + + QueuePage *page = manager->queue.first(); + r = page->pop(); + + if (page->isFinished()) { + manager->queue.removeFirst(); + delete page; + } + } while (true); if (manager->isExiting) { registerThreadInactive(); @@ -160,6 +171,7 @@ QThreadPoolPrivate:: QThreadPoolPrivate() bool QThreadPoolPrivate::tryStart(QRunnable *task) { + Q_ASSERT(task != nullptr); if (allThreads.isEmpty()) { // always create at least one thread startThread(task); @@ -180,7 +192,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task) if (!expiredThreads.isEmpty()) { // restart an expired thread QThreadPoolThread *thread = expiredThreads.dequeue(); - Q_ASSERT(thread->runnable == 0); + Q_ASSERT(thread->runnable == nullptr); ++activeThreads; @@ -196,22 +208,25 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task) return true; } -inline bool operator<(int priority, const QPair<QRunnable *, int> &p) -{ return p.second < priority; } -inline bool operator<(const QPair<QRunnable *, int> &p, int priority) -{ return priority < p.second; } +inline bool comparePriority(int priority, const QueuePage *p) +{ + return p->priority() < priority; +} void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) { + Q_ASSERT(runnable != nullptr); if (runnable->autoDelete()) ++runnable->ref; - // put it on the queue - QVector<QPair<QRunnable *, int> >::const_iterator begin = queue.constBegin(); - QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constEnd(); - if (it != begin && priority > (*(it - 1)).second) - it = std::upper_bound(begin, --it, priority); - queue.insert(it - begin, qMakePair(runnable, priority)); + for (QueuePage *page : qAsConst(queue)) { + if (page->priority() == priority && !page->isFull()) { + page->push(runnable); + return; + } + } + auto it = std::upper_bound(queue.constBegin(), queue.constEnd(), priority, comparePriority); + queue.insert(std::distance(queue.constBegin(), it), new QueuePage(runnable, priority)); } int QThreadPoolPrivate::activeThreadCount() const @@ -225,8 +240,18 @@ int QThreadPoolPrivate::activeThreadCount() const void QThreadPoolPrivate::tryToStartMoreThreads() { // try to push tasks on the queue to any available threads - while (!queue.isEmpty() && tryStart(queue.constFirst().first)) - queue.removeFirst(); + while (!queue.isEmpty()) { + QueuePage *page = queue.first(); + if (!tryStart(page->first())) + break; + + page->pop(); + + if (page->isFinished()) { + queue.removeFirst(); + delete page; + } + } } bool QThreadPoolPrivate::tooManyThreadsActive() const @@ -240,6 +265,7 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const */ void QThreadPoolPrivate::startThread(QRunnable *runnable) { + Q_ASSERT(runnable != nullptr); 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) @@ -303,12 +329,14 @@ bool QThreadPoolPrivate::waitForDone(int msecs) void QThreadPoolPrivate::clear() { QMutexLocker locker(&mutex); - for (QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constBegin(); - it != queue.constEnd(); ++it) { - QRunnable* r = it->first; - if (r->autoDelete() && !--r->ref) - delete r; + for (QueuePage *page : qAsConst(queue)) { + while (!page->isFinished()) { + QRunnable *r = page->pop(); + if (r && r->autoDelete() && !--r->ref) + delete r; + } } + qDeleteAll(queue); queue.clear(); } @@ -333,22 +361,21 @@ bool QThreadPool::tryTake(QRunnable *runnable) { Q_D(QThreadPool); - if (runnable == 0) + if (runnable == nullptr) return false; { QMutexLocker locker(&d->mutex); - auto it = d->queue.begin(); - auto end = d->queue.end(); - - while (it != end) { - if (it->first == runnable) { - d->queue.erase(it); + for (QueuePage *page : qAsConst(d->queue)) { + if (page->tryTake(runnable)) { + if (page->isFinished()) { + d->queue.removeOne(page); + delete page; + } if (runnable->autoDelete()) --runnable->ref; // undo ++ref in start() return true; } - ++it; } } diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 8b6a8cc476..d03ba9d77f 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -63,6 +63,87 @@ QT_BEGIN_NAMESPACE +class QueuePage { +public: + enum { + MaxPageSize = 256 + }; + + QueuePage(QRunnable *runnable, int pri) + : m_priority(pri) + { + push(runnable); + } + + bool isFull() { + return m_lastIndex >= MaxPageSize - 1; + } + + bool isFinished() { + return m_firstIndex > m_lastIndex; + } + + void push(QRunnable *runnable) { + Q_ASSERT(runnable != nullptr); + Q_ASSERT(!isFull()); + m_lastIndex += 1; + m_entries[m_lastIndex] = runnable; + } + + void skipToNextOrEnd() { + while (!isFinished() && m_entries[m_firstIndex] == nullptr) { + m_firstIndex += 1; + } + } + + QRunnable *first() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = m_entries[m_firstIndex]; + Q_ASSERT(runnable); + return runnable; + } + + QRunnable *pop() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = first(); + Q_ASSERT(runnable); + + // clear the entry although this should not be necessary + m_entries[m_firstIndex] = nullptr; + m_firstIndex += 1; + + // make sure the next runnable returned by first() is not a nullptr + skipToNextOrEnd(); + + return runnable; + } + + bool tryTake(QRunnable *runnable) { + Q_ASSERT(!isFinished()); + for (int i = m_firstIndex; i <= m_lastIndex; i++) { + if (m_entries[i] == runnable) { + m_entries[i] = nullptr; + if (i == m_firstIndex) { + // make sure first() does not return a nullptr + skipToNextOrEnd(); + } + return true; + } + } + return false; + } + + int priority() const { + return m_priority; + } + +private: + int m_priority = 0; + int m_firstIndex = 0; + int m_lastIndex = -1; + QRunnable *m_entries[MaxPageSize]; +}; + class QThreadPoolThread; class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate { @@ -84,12 +165,13 @@ public: bool waitForDone(int msecs); void clear(); void stealAndRunRunnable(QRunnable *runnable); + void deletePageIfFinished(QueuePage *page); mutable QMutex mutex; QList<QThreadPoolThread *> allThreads; QQueue<QThreadPoolThread *> waitingThreads; QQueue<QThreadPoolThread *> expiredThreads; - QVector<QPair<QRunnable *, int> > queue; + QVector<QueuePage*> queue; QWaitCondition noActiveThreads; int expiryTimeout = 30000; |