diff --git a/src/slic3r/GUI/Jobs/BoostThreadWorker.cpp b/src/slic3r/GUI/Jobs/BoostThreadWorker.cpp index 2c3158e4cd..c390d4e3e2 100644 --- a/src/slic3r/GUI/Jobs/BoostThreadWorker.cpp +++ b/src/slic3r/GUI/Jobs/BoostThreadWorker.cpp @@ -81,9 +81,12 @@ std::future BoostThreadWorker::call_on_main_thread(std::function } BoostThreadWorker::BoostThreadWorker(std::shared_ptr pri, - boost::thread::attributes &attribs, - const char * name) - : m_progress(std::move(pri)), m_input_queue{m_running}, m_output_queue{m_running}, m_name{name} + boost::thread::attributes &attribs, + const char *name) + : m_progress(std::move(pri)) + , m_input_queue{m_running} + , m_output_queue{m_running} + , m_name{name} { if (m_progress) m_progress->set_cancel_callback([this](){ cancel(); }); diff --git a/src/slic3r/GUI/Jobs/BoostThreadWorker.hpp b/src/slic3r/GUI/Jobs/BoostThreadWorker.hpp index 823ad9adfe..3d11097e2a 100644 --- a/src/slic3r/GUI/Jobs/BoostThreadWorker.hpp +++ b/src/slic3r/GUI/Jobs/BoostThreadWorker.hpp @@ -67,9 +67,14 @@ class BoostThreadWorker : public Worker, private Job::Ctl 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 RawQueue: public std::deque { - std::atomic *m_running_ptr = nullptr; + std::atomic *m_running_ptr; public: using std::deque::deque; @@ -79,6 +84,7 @@ class BoostThreadWorker : public Worker, private Job::Ctl void set_stopped() { m_running_ptr->store(false); } }; + // The running flag is set if a job is popped from the queue template class RawJobQueue: public RawQueue { 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 RawMsgQueue: public RawQueue { public: diff --git a/src/slic3r/GUI/Jobs/ThreadSafeQueue.hpp b/src/slic3r/GUI/Jobs/ThreadSafeQueue.hpp index df1779c06f..e0d423d4b9 100644 --- a/src/slic3r/GUI/Jobs/ThreadSafeQueue.hpp +++ b/src/slic3r/GUI/Jobs/ThreadSafeQueue.hpp @@ -32,14 +32,16 @@ class ThreadSafeQueueSPSC std::condition_variable m_cond_var; public: + + // Forward arguments to the underlying queue template ThreadSafeQueueSPSC(Qargs &&...qargs) : m_queue{Container{std::forward(qargs)...}} {} - ThreadSafeQueueSPSC(const ThreadSafeQueueSPSC&) = default; - ThreadSafeQueueSPSC(ThreadSafeQueueSPSC&&) = default; - ThreadSafeQueueSPSC& operator=(const ThreadSafeQueueSPSC&) = default; - ThreadSafeQueueSPSC& operator=(ThreadSafeQueueSPSC &&) = default; + ThreadSafeQueueSPSC(const ThreadSafeQueueSPSC&) = delete; + ThreadSafeQueueSPSC(ThreadSafeQueueSPSC&&) = delete; + ThreadSafeQueueSPSC& operator=(const ThreadSafeQueueSPSC&) = delete; + ThreadSafeQueueSPSC& operator=(ThreadSafeQueueSPSC &&) = delete; // Consume one element, block if the queue is empty. template