In my application I have an event thread and a render thread. I wrote a custom thread class that is able to execute tasks (function pointers) in a fixed interval so I can pass work between different threads if needed.
Here is the setup: In the event thread I parse a file that will create models, but before I can create models I have to delete the old ones, so naturally I just add the task of clearing the models like this:
WindowThread::getInstance()->addTask([this]() {
this->viewport->clearModels();
});
This function will eventually be executed by the window thread, which seems to work fine, however when debugging with valgrind it reports the following error: valgrind invalid read of size 8
in the line where clearModels() is called. After a bit of googling the issue seems to be that the viewport pointer (or this, I don't know for sure) is outside of the memory address area of the window thread, which makes sense since the lambda function was created in the event thread.
Is there a way to fix this "error" by somehow moving the pointer/lambda into the other threads memory area?
FThread::addTask(const std::function<void()> &task) adds the given task to a std::queue (which is locked by a mutex beforehand) from the thread it is called in. Eventually the queue will be processed by the thread the task was added to.
void FThread::addTask(const std::function<void()> &task)
{
if (this->m_running && this->m_taskQueueMode != QUEUE_DISABLED)
{
this->m_taskQueueMutex.lock();
this->m_backTaskQueue->push(task);
this->m_taskQueueMutex.unlock();
}
}
void FThread::processTaskQueue()
{
this->m_taskQueueMutex.lock();
std::queue<std::function<void()>> *tmp = this->m_frontTaskQueue;
this->m_frontTaskQueue = this->m_backTaskQueue;
this->m_backTaskQueue = tmp;
this->m_taskQueueMutex.unlock();
while (!this->m_frontTaskQueue->empty())
{
this->m_frontTaskQueue->front()();
this->m_frontTaskQueue->pop();
}
}
The task queue is setup in a double buffered way so processing the current tasks doesn't block adding new ones.
EDIT: The clearModels() method is just deleting every pointer in a vector and then clearing the vector.
void Viewport::clearModels()
{
if (!this->models.empty())
{
for (auto *model : this->models)
delete model;
this->models.clear();
}
this->hiddenModels.clear();
}