Fix of a crash when using active_step_add_warning on PrintObjects

PrintObjectBase::status_update_warnings called PrintBase::status_update_warnings, which in turn set
SlicingStatus flag to UPDATE_PRINT_STEP_WARNINGS (instead of UPDATE_PRINT_OBEJCT_STEP_WARNINGS) and
saved its own ObjectID. This led to spurious and hard to read thread-unsafe crashes.
This commit is contained in:
Lukas Matena 2021-02-26 07:57:48 +01:00
parent a53de51b22
commit 19cfeb1a78
2 changed files with 10 additions and 8 deletions

View File

@ -94,12 +94,14 @@ std::string PrintBase::output_filepath(const std::string &path, const std::strin
return path; return path;
} }
void PrintBase::status_update_warnings(ObjectID object_id, int step, PrintStateBase::WarningLevel /* warning_level */, const std::string &message) void PrintBase::status_update_warnings(int step, PrintStateBase::WarningLevel /* warning_level */, const std::string &message, const PrintObjectBase* print_object)
{ {
if (this->m_status_callback) if (this->m_status_callback) {
m_status_callback(SlicingStatus(*this, step)); auto status = print_object ? SlicingStatus(*print_object, step) : SlicingStatus(*this, step);
m_status_callback(status);
}
else if (! message.empty()) else if (! message.empty())
printf("%s warning: %s\n", (object_id == this->id()) ? "print" : "print object", message.c_str()); printf("%s warning: %s\n", print_object ? "print_object" : "print", message.c_str());
} }
tbb::mutex& PrintObjectBase::state_mutex(PrintBase *print) tbb::mutex& PrintObjectBase::state_mutex(PrintBase *print)
@ -114,7 +116,7 @@ std::function<void()> PrintObjectBase::cancel_callback(PrintBase *print)
void PrintObjectBase::status_update_warnings(PrintBase *print, int step, PrintStateBase::WarningLevel warning_level, const std::string &message) void PrintObjectBase::status_update_warnings(PrintBase *print, int step, PrintStateBase::WarningLevel warning_level, const std::string &message)
{ {
print->status_update_warnings(this->id(), step, warning_level, message); print->status_update_warnings(step, warning_level, message, this);
} }
} // namespace Slic3r } // namespace Slic3r

View File

@ -481,7 +481,7 @@ protected:
// Notify UI about a new warning of a milestone "step" on this PrintBase. // Notify UI about a new warning of a milestone "step" on this PrintBase.
// The UI will be notified by calling a status callback. // The UI will be notified by calling a status callback.
// If no status callback is registered, the message is printed to console. // If no status callback is registered, the message is printed to console.
void status_update_warnings(ObjectID object_id, int step, PrintStateBase::WarningLevel warning_level, const std::string &message); void status_update_warnings(int step, PrintStateBase::WarningLevel warning_level, const std::string &message, const PrintObjectBase* print_object = nullptr);
// If the background processing stop was requested, throw CanceledException. // If the background processing stop was requested, throw CanceledException.
// To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly. // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
@ -528,7 +528,7 @@ protected:
PrintStateBase::TimeStamp set_done(PrintStepEnum step) { PrintStateBase::TimeStamp set_done(PrintStepEnum step) {
std::pair<PrintStateBase::TimeStamp, bool> status = m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); std::pair<PrintStateBase::TimeStamp, bool> status = m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); });
if (status.second) if (status.second)
this->status_update_warnings(this->id(), static_cast<int>(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); this->status_update_warnings(static_cast<int>(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string());
return status.first; return status.first;
} }
bool invalidate_step(PrintStepEnum step) bool invalidate_step(PrintStepEnum step)
@ -550,7 +550,7 @@ protected:
std::pair<PrintStepEnum, bool> active_step = m_state.active_step_add_warning(warning_level, message, message_id, this->state_mutex()); std::pair<PrintStepEnum, bool> active_step = m_state.active_step_add_warning(warning_level, message, message_id, this->state_mutex());
if (active_step.second) if (active_step.second)
// Update UI. // Update UI.
this->status_update_warnings(this->id(), static_cast<int>(active_step.first), warning_level, message); this->status_update_warnings(static_cast<int>(active_step.first), warning_level, message);
} }
private: private: