Add a constructor for QRunnable from anonymous functions
This makes it easier to create one without having to create a derivative class. The patch also adds a path to avoid using QRunnable directly in QThreadPool. Change-Id: I9caa7dabb6f641b547d4771c863aa6ab7f01b704 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
parent
6c4e0f2d2d
commit
c76dd72dc6
@ -114,4 +114,31 @@ QRunnable::~QRunnable()
|
||||
\sa autoDelete(), QThreadPool
|
||||
*/
|
||||
|
||||
class FunctionRunnable : public QRunnable
|
||||
{
|
||||
std::function<void()> m_functor;
|
||||
public:
|
||||
FunctionRunnable(std::function<void()> functor) : m_functor(std::move(functor))
|
||||
{
|
||||
}
|
||||
void run() override
|
||||
{
|
||||
m_functor();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\since 5.15
|
||||
|
||||
Creates a QRunnable that calls \a fun in run().
|
||||
|
||||
Auto-deletion is enabled by default.
|
||||
|
||||
\sa run(), autoDelete()
|
||||
*/
|
||||
QRunnable *QRunnable::create(std::function<void()> fun)
|
||||
{
|
||||
return new FunctionRunnable(std::move(fun));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define QRUNNABLE_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <functional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -59,6 +60,7 @@ public:
|
||||
|
||||
QRunnable() : ref(0) { }
|
||||
virtual ~QRunnable();
|
||||
static QRunnable *create(std::function<void()> fun);
|
||||
|
||||
bool autoDelete() const { return ref != -1; }
|
||||
void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; }
|
||||
|
@ -511,6 +511,22 @@ void QThreadPool::start(QRunnable *runnable, int priority)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.15
|
||||
|
||||
Reserves a thread and uses it to run \a fun, unless this thread will
|
||||
make the current thread count exceed maxThreadCount(). In that case,
|
||||
\a fun is added to a run queue instead. The \a priority argument can
|
||||
be used to control the run queue's order of execution.
|
||||
*/
|
||||
void QThreadPool::start(std::function<void()> fun, int priority)
|
||||
{
|
||||
if (!fun)
|
||||
return;
|
||||
start(QRunnable::create(std::move(fun)), priority);
|
||||
}
|
||||
|
||||
/*!
|
||||
Attempts to reserve a thread to run \a runnable.
|
||||
|
||||
@ -542,6 +558,22 @@ bool QThreadPool::tryStart(QRunnable *runnable)
|
||||
return d->tryStart(runnable);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.15
|
||||
Attempts to reserve a thread to run \a fun.
|
||||
|
||||
If no threads are available at the time of calling, then this function
|
||||
does nothing and returns \c false. Otherwise, \a fun is run immediately
|
||||
using one available thread and this function returns \c true.
|
||||
*/
|
||||
bool QThreadPool::tryStart(std::function<void()> fun)
|
||||
{
|
||||
if (!fun)
|
||||
return false;
|
||||
return tryStart(QRunnable::create(std::move(fun)));
|
||||
}
|
||||
|
||||
/*! \property QThreadPool::expiryTimeout
|
||||
|
||||
Threads that are unused for \a expiryTimeout milliseconds are considered
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include <QtCore/qthread.h>
|
||||
#include <QtCore/qrunnable.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
QT_REQUIRE_CONFIG(thread);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -70,6 +72,9 @@ public:
|
||||
void start(QRunnable *runnable, int priority = 0);
|
||||
bool tryStart(QRunnable *runnable);
|
||||
|
||||
void start(std::function<void()> fun, int priority = 0);
|
||||
bool tryStart(std::function<void()> fun);
|
||||
|
||||
int expiryTimeout() const;
|
||||
void setExpiryTimeout(int expiryTimeout);
|
||||
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void runFunction();
|
||||
void runFunction2();
|
||||
void createThreadRunFunction();
|
||||
void runMultiple();
|
||||
void waitcomplete();
|
||||
@ -160,17 +161,27 @@ void tst_QThreadPool::runFunction()
|
||||
{
|
||||
QThreadPool manager;
|
||||
testFunctionCount = 0;
|
||||
manager.start(createTask(noSleepTestFunction));
|
||||
manager.start(noSleepTestFunction);
|
||||
}
|
||||
QCOMPARE(testFunctionCount, 1);
|
||||
}
|
||||
|
||||
void tst_QThreadPool::runFunction2()
|
||||
{
|
||||
int localCount = 0;
|
||||
{
|
||||
QThreadPool manager;
|
||||
manager.start([&]() { ++localCount; });
|
||||
}
|
||||
QCOMPARE(localCount, 1);
|
||||
}
|
||||
|
||||
void tst_QThreadPool::createThreadRunFunction()
|
||||
{
|
||||
{
|
||||
QThreadPool manager;
|
||||
testFunctionCount = 0;
|
||||
manager.start(createTask(noSleepTestFunction));
|
||||
manager.start(noSleepTestFunction);
|
||||
}
|
||||
|
||||
QCOMPARE(testFunctionCount, 1);
|
||||
@ -184,7 +195,7 @@ void tst_QThreadPool::runMultiple()
|
||||
QThreadPool manager;
|
||||
testFunctionCount = 0;
|
||||
for (int i = 0; i < runs; ++i) {
|
||||
manager.start(createTask(sleepTestFunctionMutex));
|
||||
manager.start(sleepTestFunctionMutex);
|
||||
}
|
||||
}
|
||||
QCOMPARE(testFunctionCount, runs);
|
||||
@ -193,7 +204,7 @@ void tst_QThreadPool::runMultiple()
|
||||
QThreadPool manager;
|
||||
testFunctionCount = 0;
|
||||
for (int i = 0; i < runs; ++i) {
|
||||
manager.start(createTask(noSleepTestFunctionMutex));
|
||||
manager.start(noSleepTestFunctionMutex);
|
||||
}
|
||||
}
|
||||
QCOMPARE(testFunctionCount, runs);
|
||||
@ -201,7 +212,7 @@ void tst_QThreadPool::runMultiple()
|
||||
{
|
||||
QThreadPool manager;
|
||||
for (int i = 0; i < 500; ++i)
|
||||
manager.start(createTask(emptyFunct));
|
||||
manager.start(emptyFunct);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +222,7 @@ void tst_QThreadPool::waitcomplete()
|
||||
const int runs = 500;
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
QThreadPool pool;
|
||||
pool.start(createTask(noSleepTestFunction));
|
||||
pool.start(noSleepTestFunction);
|
||||
}
|
||||
QCOMPARE(testFunctionCount, runs);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user