From 10eddb0d9e6e025454396cff1a61c00fe51be19d Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 3 Sep 2014 00:34:31 -0300 Subject: [PATCH] Avoid crash if FilterWorker cannot lock the current sprite to write it (fix #478) --- src/app/commands/filters/filter_worker.cpp | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/app/commands/filters/filter_worker.cpp b/src/app/commands/filters/filter_worker.cpp index 6fd24fcc7..929ea119a 100644 --- a/src/app/commands/filters/filter_worker.cpp +++ b/src/app/commands/filters/filter_worker.cpp @@ -25,6 +25,7 @@ #include "app/app.h" #include "app/commands/filters/filter_manager_impl.h" +#include "app/console.h" #include "app/ini_file.h" #include "app/modules/editors.h" #include "app/modules/gui.h" @@ -47,8 +48,7 @@ static const int kMonitoringPeriod = 100; // modify the sprite, and the main thread to monitoring the progress // (and given to the user the possibility to cancel the process). -class FilterWorker : public FilterManagerImpl::IProgressDelegate -{ +class FilterWorker : public FilterManagerImpl::IProgressDelegate { public: FilterWorker(FilterManagerImpl* filterMgr); ~FilterWorker(); @@ -71,11 +71,13 @@ private: FilterManagerImpl* m_filterMgr; // Effect to be applied. base::mutex m_mutex; // Mutex to access to 'pos', 'done' and 'cancelled' fields in different threads. float m_pos; // Current progress position - bool m_done : 1; // Was the effect completelly applied? - bool m_cancelled : 1; // Was the effect cancelled by the user? + bool m_done; // Was the effect completelly applied? + bool m_cancelled; // Was the effect cancelled by the user? + bool m_abort; // An exception was thrown ui::Timer m_timer; // Monitoring timer to update the progress-bar Progress* m_progressBar; // The progress-bar. AlertPtr m_alertWindow; // Alert for the user to cancel the filter-progress if he wants. + std::string m_error; }; FilterWorker::FilterWorker(FilterManagerImpl* filterMgr) @@ -87,11 +89,12 @@ FilterWorker::FilterWorker(FilterManagerImpl* filterMgr) m_pos = 0.0; m_done = false; m_cancelled = false; + m_abort = false; m_progressBar = StatusBar::instance()->addProgress(); m_alertWindow = ui::Alert::create(PACKAGE - "<applyToTarget(); + try { + // Apply the filter + m_filterMgr->applyToTarget(); - // Mark the work as 'done'. - scoped_lock lock(m_mutex); - m_done = true; + // Mark the work as 'done'. + scoped_lock lock(m_mutex); + m_done = true; + } + catch (std::exception& e) { + m_error = e.what(); + m_abort = true; + } } // Called by the GUI monitor (a timer in the gui module that is called @@ -173,7 +187,7 @@ void FilterWorker::onMonitoringTick() if (m_progressBar) m_progressBar->setPos(m_pos); - if (m_done) + if (m_done || m_abort) m_alertWindow->closeWindow(NULL); }