diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 1616fb9fabaa3de7b99c93dac8f208eff9245f69..a7d52f9652e5300a95af86871a1ccd60ac247745 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -215,7 +215,7 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) // put it on the queue QList<QPair<QRunnable *, int> >::const_iterator begin = queue.constBegin(); QList<QPair<QRunnable *, int> >::const_iterator it = queue.constEnd(); - if (it != begin && priority < (*(it - 1)).second) + if (it != begin && priority > (*(it - 1)).second) it = std::upper_bound(begin, --it, priority); queue.insert(it - begin, qMakePair(runnable, priority)); runnableReady.wakeOne(); diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index a93a94a4702ab48f846151f248d0b94e0b94862b..3c0e132a0a317a6eeee9f3b8cc25037d53d2b7a6 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -94,6 +94,8 @@ private slots: void tryStart(); void tryStartPeakThreadCount(); void tryStartCount(); + void priorityStart_data(); + void priorityStart(); void waitForDone(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); @@ -747,6 +749,57 @@ void tst_QThreadPool::tryStartCount() } } +void tst_QThreadPool::priorityStart_data() +{ + QTest::addColumn<int>("otherCount"); + QTest::newRow("0") << 0; + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; +} + +void tst_QThreadPool::priorityStart() +{ + class Holder : public QRunnable + { + public: + QSemaphore &sem; + Holder(QSemaphore &sem) : sem(sem) {} + void run() + { + sem.acquire(); + } + }; + class Runner : public QRunnable + { + public: + QAtomicPointer<QRunnable> &ptr; + Runner(QAtomicPointer<QRunnable> &ptr) : ptr(ptr) {} + void run() + { + ptr.testAndSetRelaxed(0, this); + } + }; + + QFETCH(int, otherCount); + QSemaphore sem; + QAtomicPointer<QRunnable> firstStarted; + QRunnable *expected; + QThreadPool threadPool; + threadPool.setMaxThreadCount(1); // start only one thread at a time + + // queue the holder first + // We need to be sure that all threads are active when we + // queue the two Runners + threadPool.start(new Holder(sem)); + while (otherCount--) + threadPool.start(new Runner(firstStarted), 0); // priority 0 + threadPool.start(expected = new Runner(firstStarted), 1); // priority 1 + + sem.release(); + QVERIFY(threadPool.waitForDone()); + QCOMPARE(firstStarted.load(), expected); +} + void tst_QThreadPool::waitForDone() { QTime total, pass;