Merge branch 'tm_fix_gcc_crash'

This commit is contained in:
tamasmeszaros 2023-12-07 16:03:38 +01:00
commit dea433611d
3 changed files with 20 additions and 8 deletions

View File

@ -81,9 +81,12 @@ std::future<void> BoostThreadWorker::call_on_main_thread(std::function<void ()>
} }
BoostThreadWorker::BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri, BoostThreadWorker::BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri,
boost::thread::attributes &attribs, boost::thread::attributes &attribs,
const char * name) const char *name)
: m_progress(std::move(pri)), m_input_queue{m_running}, m_output_queue{m_running}, m_name{name} : m_progress(std::move(pri))
, m_input_queue{m_running}
, m_output_queue{m_running}
, m_name{name}
{ {
if (m_progress) if (m_progress)
m_progress->set_cancel_callback([this](){ cancel(); }); m_progress->set_cancel_callback([this](){ cancel(); });

View File

@ -67,9 +67,14 @@ class BoostThreadWorker : public Worker, private Job::Ctl
void deliver(BoostThreadWorker &runner); void deliver(BoostThreadWorker &runner);
}; };
// The m_running state flag needs special attention. Previously, it was set simply in the run()
// method whenever a new job was taken from the input queue and unset after the finalize message
// was pushed into the output queue. This was not correct. It must not be possible to consume
// the finalize message before the flag gets unset, these two operations must be done atomically
// So the underlying queues are here extended to support handling of this m_running flag.
template<class El> template<class El>
class RawQueue: public std::deque<El> { class RawQueue: public std::deque<El> {
std::atomic<bool> *m_running_ptr = nullptr; std::atomic<bool> *m_running_ptr;
public: public:
using std::deque<El>::deque; using std::deque<El>::deque;
@ -79,6 +84,7 @@ class BoostThreadWorker : public Worker, private Job::Ctl
void set_stopped() { m_running_ptr->store(false); } void set_stopped() { m_running_ptr->store(false); }
}; };
// The running flag is set if a job is popped from the queue
template<class El> template<class El>
class RawJobQueue: public RawQueue<El> { class RawJobQueue: public RawQueue<El> {
public: public:
@ -90,6 +96,7 @@ class BoostThreadWorker : public Worker, private Job::Ctl
} }
}; };
// The running flag is unset when the finalize message is pushed into the queue
template<class El> template<class El>
class RawMsgQueue: public RawQueue<El> { class RawMsgQueue: public RawQueue<El> {
public: public:

View File

@ -32,14 +32,16 @@ class ThreadSafeQueueSPSC
std::condition_variable m_cond_var; std::condition_variable m_cond_var;
public: public:
// Forward arguments to the underlying queue
template<class...Qargs> template<class...Qargs>
ThreadSafeQueueSPSC(Qargs &&...qargs) ThreadSafeQueueSPSC(Qargs &&...qargs)
: m_queue{Container<T, ContainerArgs...>{std::forward<Qargs>(qargs)...}} {} : m_queue{Container<T, ContainerArgs...>{std::forward<Qargs>(qargs)...}} {}
ThreadSafeQueueSPSC(const ThreadSafeQueueSPSC&) = default; ThreadSafeQueueSPSC(const ThreadSafeQueueSPSC&) = delete;
ThreadSafeQueueSPSC(ThreadSafeQueueSPSC&&) = default; ThreadSafeQueueSPSC(ThreadSafeQueueSPSC&&) = delete;
ThreadSafeQueueSPSC& operator=(const ThreadSafeQueueSPSC&) = default; ThreadSafeQueueSPSC& operator=(const ThreadSafeQueueSPSC&) = delete;
ThreadSafeQueueSPSC& operator=(ThreadSafeQueueSPSC &&) = default; ThreadSafeQueueSPSC& operator=(ThreadSafeQueueSPSC &&) = delete;
// Consume one element, block if the queue is empty. // Consume one element, block if the queue is empty.
template<class Fn> template<class Fn>