Merge pull request #758 from flowln/fix_process_events_backstab
This commit is contained in:
commit
04e4900415
@ -110,14 +110,14 @@ void ConcurrentTask::startNext()
|
||||
setStepStatus(next->isMultiStep() ? next->getStepStatus() : next->getStatus());
|
||||
updateState();
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
QMetaObject::invokeMethod(next.get(), &Task::start, Qt::QueuedConnection);
|
||||
|
||||
// Allow going up the number of concurrent tasks in case of tasks being added in the middle of a running task.
|
||||
int num_starts = m_total_max_size - m_doing.size();
|
||||
for (int i = 0; i < num_starts; i++)
|
||||
QMetaObject::invokeMethod(this, &ConcurrentTask::startNext, Qt::QueuedConnection);
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void ConcurrentTask::subTaskSucceeded(Task::Ptr task)
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <QTest>
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
#include <tasks/ConcurrentTask.h>
|
||||
#include <tasks/MultipleOptionsTask.h>
|
||||
@ -11,6 +13,9 @@ class BasicTask : public Task {
|
||||
|
||||
friend class TaskTest;
|
||||
|
||||
public:
|
||||
BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {}
|
||||
|
||||
private:
|
||||
void executeTask() override
|
||||
{
|
||||
@ -30,6 +35,42 @@ class BasicTask_MultiStep : public Task {
|
||||
void executeTask() override {};
|
||||
};
|
||||
|
||||
class BigConcurrentTask : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
ConcurrentTask big_task;
|
||||
|
||||
void run() override
|
||||
{
|
||||
QTimer deadline;
|
||||
deadline.setInterval(10000);
|
||||
connect(&deadline, &QTimer::timeout, this, [this]{ passed_the_deadline = true; });
|
||||
deadline.start();
|
||||
|
||||
// NOTE: Arbitrary value that manages to trigger a problem when there is one.
|
||||
static const unsigned s_num_tasks = 1 << 14;
|
||||
auto sub_tasks = new BasicTask*[s_num_tasks];
|
||||
|
||||
for (unsigned i = 0; i < s_num_tasks; i++) {
|
||||
sub_tasks[i] = new BasicTask(false);
|
||||
big_task.addTask(sub_tasks[i]);
|
||||
}
|
||||
|
||||
big_task.run();
|
||||
|
||||
while (!big_task.isFinished() && !passed_the_deadline)
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
public:
|
||||
bool passed_the_deadline = false;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
};
|
||||
|
||||
class TaskTest : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
@ -183,6 +224,25 @@ class TaskTest : public QObject {
|
||||
return t.isFinished();
|
||||
}, 1000), "Task didn't finish as it should.");
|
||||
}
|
||||
|
||||
void test_stackOverflowInConcurrentTask()
|
||||
{
|
||||
QEventLoop loop;
|
||||
|
||||
auto thread = new BigConcurrentTask;
|
||||
// NOTE: This is an arbitrary value, big enough to not cause problems on normal execution, but low enough
|
||||
// so that the number of tasks that needs to get ran to potentially cause a problem isn't too big.
|
||||
thread->setStackSize(32 * 1024);
|
||||
|
||||
connect(thread, &BigConcurrentTask::finished, &loop, &QEventLoop::quit);
|
||||
|
||||
thread->start();
|
||||
|
||||
loop.exec();
|
||||
|
||||
QVERIFY(!thread->passed_the_deadline);
|
||||
thread->deleteLater();
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(TaskTest)
|
||||
|
Loading…
Reference in New Issue
Block a user