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:
@@ -229,7 +229,7 @@ void PersistentStorage::finishInjection()
|
||||
{
|
||||
MessageShowErrors msg(errorCount);
|
||||
msg.setSendAsTask(false);
|
||||
msg.dispatch();
|
||||
msg.dispatchImmediately();
|
||||
}
|
||||
m_preInjectionErrorCount = -1;
|
||||
}
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,7 +33,7 @@ private:
|
||||
TaskScheduler(const TaskScheduler&);
|
||||
void operator=(const TaskScheduler&);
|
||||
|
||||
void updateTasks();
|
||||
void processTasks();
|
||||
|
||||
virtual void handleMessage(MessageInterruptTasks* message);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
int order = 0;
|
||||
TestTask task(&order, 1);
|
||||
|
||||
task.execute();
|
||||
task.executeTask();
|
||||
|
||||
TS_ASSERT_EQUALS(3, order);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user