logic: Fixed crashes and halting during indexing

* Fixed CPPSqliteException being thrown due to not properly destructed statement in addError
* Fixed indexer getting stuck after building caches because MessageFinishedParsing was interrupted
* removed Message::cancel() method and all related code

bug id = 105
This commit is contained in:
Eberhard Graether
2016-06-29 14:10:26 +02:00
parent ba3316008a
commit cba0cfad65
13 changed files with 78 additions and 83 deletions
+1 -1
View File
@@ -229,7 +229,7 @@ void PersistentStorage::finishInjection()
{
MessageShowErrors msg(errorCount);
msg.setSendAsTask(false);
msg.dispatch();
msg.dispatchImmediately();
}
m_preInjectionErrorCount = -1;
}
+2
View File
@@ -223,6 +223,8 @@ Id SqliteStorage::addError(const std::string& message, bool fatal, const std::st
return q.getIntField(0, -1);
}
stmt.finalize();
stmt = m_database.compileStatement((
"INSERT INTO error(message, fatal, file_path, line_number, column_number) "
"VALUES (?, " + std::to_string(fatal) + ", '" + filePath +
-12
View File
@@ -11,7 +11,6 @@ public:
: m_isReplayed(false)
, m_sendAsTask(true)
, m_keepContent(false)
, m_cancelled(false)
, m_isLast(true)
, m_isLogged(true)
{
@@ -74,16 +73,6 @@ public:
return m_keepContent;
}
void cancel()
{
m_cancelled = true;
}
bool cancelled()
{
return m_cancelled;
}
virtual void print(std::ostream& os) const = 0;
std::string str() const
@@ -98,7 +87,6 @@ private:
bool m_isReplayed;
bool m_sendAsTask;
bool m_keepContent;
bool m_cancelled;
bool m_isLast;
bool m_isLogged;
};
+1 -6
View File
@@ -253,11 +253,6 @@ void MessageQueue::sendMessage(std::shared_ptr<MessageBase> message)
listener->handleMessageBase(message.get());
m_listenersMutex.lock();
}
if (message->cancelled())
{
break;
}
}
}
@@ -277,7 +272,7 @@ void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message, bool
[listenerId, message]()
{
MessageListenerBase* listener = MessageQueue::getInstance()->getListenerById(listenerId);
if (listener && !message->cancelled())
if (listener)
{
listener->handleMessageBase(message.get());
}
@@ -25,11 +25,6 @@ public:
return "MessageFinishedParsing";
}
virtual void dispatch()
{
Message<MessageFinishedParsing>::dispatch();
}
std::string getStatusStr() const
{
if (loadedOnly)
+40 -41
View File
@@ -27,63 +27,62 @@ Task::TaskState Task::getState() const
return m_state;
}
Task::TaskState Task::process(bool interruptTask)
Task::TaskState Task::processTask()
{
if (interruptTask)
switch (m_state)
{
switch (m_state)
case STATE_NEW:
case STATE_CANCELED:
enter();
case STATE_RUNNING:
{
case STATE_NEW:
case STATE_CANCELED:
break;
case STATE_RUNNING:
interrupt();
exit();
break;
case STATE_FINISHED:
revert();
break;
}
setState(STATE_CANCELED);
}
else
{
switch (m_state)
{
case STATE_NEW:
case STATE_CANCELED:
enter();
case STATE_RUNNING:
TaskState newState = update();
if (newState == STATE_NEW || newState == STATE_CANCELED)
{
TaskState newState = update();
if (newState == STATE_NEW || newState == STATE_CANCELED)
{
LOG_ERROR("Task can't change to state NEW or CANCELLED");
return m_state;
}
LOG_ERROR("Task can't change to state NEW or CANCELLED");
return m_state;
}
setState(newState);
if (m_state == STATE_FINISHED)
{
exit();
}
setState(newState);
if (m_state == STATE_FINISHED)
{
exit();
}
break;
case STATE_FINISHED:
break;
}
break;
case STATE_FINISHED:
break;
}
return m_state;
}
void Task::execute()
Task::TaskState Task::interruptTask()
{
switch (m_state)
{
case STATE_NEW:
case STATE_CANCELED:
break;
case STATE_RUNNING:
interrupt();
exit();
break;
case STATE_FINISHED:
revert();
break;
}
setState(STATE_CANCELED);
return m_state;
}
void Task::executeTask()
{
TaskState state;
do
{
state = process(false);
state = processTask();
}
while (state != STATE_FINISHED);
}
+4 -2
View File
@@ -22,8 +22,10 @@ public:
TaskState getState() const;
TaskState process(bool interruptTask);
void execute();
TaskState processTask();
TaskState interruptTask();
void executeTask();
virtual void enter() = 0;
virtual TaskState update() = 0;
@@ -21,7 +21,7 @@ Task::TaskState TaskGroupParallel::update()
{
for (size_t i = 0; i < m_tasks.size(); i++)
{
m_threads.push_back(std::thread(&TaskGroupParallel::processTask, this, m_tasks[i]));
m_threads.push_back(std::thread(&TaskGroupParallel::processTaskThreaded, this, m_tasks[i]));
std::lock_guard<std::mutex> lock(m_activeTaskCountMutex);
m_activeTaskCount++;
@@ -63,12 +63,19 @@ void TaskGroupParallel::revert()
}
void TaskGroupParallel::processTask(std::shared_ptr<Task> task)
void TaskGroupParallel::processTaskThreaded(std::shared_ptr<Task> task)
{
Task::TaskState state = Task::STATE_NEW;
while (state != Task::STATE_FINISHED && state != Task::STATE_CANCELED)
{
state = task->process(m_interrupt);
if (m_interrupt)
{
state = task->interruptTask();
}
else
{
state = task->processTask();
}
}
{
@@ -21,7 +21,7 @@ public:
virtual void revert();
private:
void processTask(std::shared_ptr<Task> task);
void processTaskThreaded(std::shared_ptr<Task> task);
volatile bool m_interrupt;
bool m_running;
@@ -27,7 +27,7 @@ Task::TaskState TaskGroupSequential::update()
std::shared_ptr<Task> task = m_tasks[m_taskIndex];
TaskState state = task->process(false);
TaskState state = task->processTask();
if (state == Task::STATE_FINISHED && size_t(m_taskIndex + 1) == m_tasks.size())
{
@@ -47,7 +47,7 @@ void TaskGroupSequential::interrupt()
{
for (int i = m_taskIndex; i >= 0; i--)
{
m_tasks[i]->process(true);
m_tasks[i]->interruptTask();
}
}
}
@@ -56,6 +56,6 @@ void TaskGroupSequential::revert()
{
for (int i = m_tasks.size() - 1; i >= 0; i--)
{
m_tasks[i]->process(true);
m_tasks[i]->interruptTask();
}
}
+14 -7
View File
@@ -66,7 +66,7 @@ void TaskScheduler::startSchedulerLoop()
while (true)
{
updateTasks();
processTasks();
{
std::lock_guard<std::mutex> lock(m_loopMutex);
@@ -141,26 +141,33 @@ TaskScheduler::TaskScheduler()
{
}
void TaskScheduler::updateTasks()
void TaskScheduler::processTasks()
{
std::lock_guard<std::mutex> lock(m_tasksMutex);
bool interrupt = m_interruptTask;
while (m_tasks.size())
{
bool interrupt = m_interruptTask;
m_interruptTask = false;
std::shared_ptr<Task> task = m_tasks.front();
Task::TaskState state;
m_tasksMutex.unlock();
Task::TaskState state = task->process(interrupt);
if (interrupt)
{
state = task->interruptTask();
}
else
{
state = task->processTask();
}
m_tasksMutex.lock();
if (state == Task::STATE_FINISHED || state == Task::STATE_CANCELED)
{
m_tasks.pop_front();
}
interrupt = m_interruptTask;
}
m_interruptTask = false;
+1 -1
View File
@@ -33,7 +33,7 @@ private:
TaskScheduler(const TaskScheduler&);
void operator=(const TaskScheduler&);
void updateTasks();
void processTasks();
virtual void handleMessage(MessageInterruptTasks* message);
+1 -1
View File
@@ -32,7 +32,7 @@ public:
int order = 0;
TestTask task(&order, 1);
task.execute();
task.executeTask();
TS_ASSERT_EQUALS(3, order);