From ad4de928f6ef9d44877bb92a7b1a8d3a035c7010 Mon Sep 17 00:00:00 2001 From: Justin Wilson Date: Thu, 9 Jan 2025 14:50:55 -0600 Subject: [PATCH] Implement weak pointer usage in thread to ensure valid pointer Fixes: Modelbuilder crash when exiting project with resources --- smtk/view/PhraseModel.cxx | 42 +++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/smtk/view/PhraseModel.cxx b/smtk/view/PhraseModel.cxx index 209663183a..c5a989e6fd 100644 --- a/smtk/view/PhraseModel.cxx +++ b/smtk/view/PhraseModel.cxx @@ -894,30 +894,34 @@ void PhraseModel::triggerDataChanged() bool expected = false; if (std::atomic_compare_exchange_strong(&m_pending, &expected, true)) { - std::function invokeContentObserversInternal = [this]() { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::weak_ptr weak = this->shared_from_this(); + std::function invokeContentObserversInternal = [weak]() { + if (auto self = weak.lock()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); - // Clear the "pending-timer" bit before we start signaling observers - // Otherwise, it is possible to miss an incoming signal that more - // content has changed while we are busy invoking observers. - m_pending.store(false); + // Clear the "pending-timer" bit before we start signaling observers + // Otherwise, it is possible to miss an incoming signal that more + // content has changed while we are busy invoking observers. + self->m_pending.store(false); - // m_contentObservers(); // TODO: Alternative to the below? - auto rootPhrase = this->root(); - if (!rootPhrase || rootPhrase->subphrases().empty()) - { - return DescriptivePhrases{}; - } + // m_contentObservers(); // TODO: Alternative to the below? - std::vector i0; - std::vector i1; - // It is doubtful trees with 64 levels will be useful; reserve - // that much space so recursion does not cause reallocation. - i0.reserve(64); - i1.reserve(64); + auto rootPhrase = self->root(); + if (!rootPhrase || rootPhrase->subphrases().empty()) + { + return DescriptivePhrases{}; + } - recursiveTrigger(rootPhrase, i0, i1); + std::vector i0; + std::vector i1; + // It is doubtful trees with 64 levels will be useful; reserve + // that much space so recursion does not cause reallocation. + i0.reserve(64); + i1.reserve(64); + self->recursiveTrigger(rootPhrase, i0, i1); + } return DescriptivePhrases{}; }; std::thread runme(invokeContentObserversInternal); -- GitLab