Commit d9ce183d authored by Lukáš Tvrdý's avatar Lukáš Tvrdý

Fix crashes related to progress reporting and cancelling gmic actions

Cancelling and progress reporting has to be synchronized:
G'Mic uses raw pointers for indicating progress and
checking if the action is cancelled. KisGmicCommand
is destroyed by KisProcessingApplicator, so KisGmicApplicator
does not know when it is deleted and when it is safe
to read/write to pointers of cancel event and progress report
parent fabb3451
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
KisGmicApplicator::KisGmicApplicator():m_applicator(0),m_applicatorStrokeEnded(false),m_progress(0),m_cancel(0) KisGmicApplicator::KisGmicApplicator():m_applicator(0),m_applicatorStrokeEnded(false),m_progress(0),m_cancel(0)
{ {
m_mutex = QSharedPointer<QMutex>(new QMutex());
} }
KisGmicApplicator::~KisGmicApplicator() KisGmicApplicator::~KisGmicApplicator()
...@@ -89,6 +90,7 @@ void KisGmicApplicator::preview() ...@@ -89,6 +90,7 @@ void KisGmicApplicator::preview()
// apply gmic filters to provided layers // apply gmic filters to provided layers
const char * customCommands = m_customCommands.isNull() ? 0 : m_customCommands.constData(); const char * customCommands = m_customCommands.isNull() ? 0 : m_customCommands.constData();
KisGmicCommand * gmicCommand = new KisGmicCommand(m_gmicCommand, gmicLayers, customCommands); KisGmicCommand * gmicCommand = new KisGmicCommand(m_gmicCommand, gmicLayers, customCommands);
gmicCommand->setMutex(m_mutex);
connect(gmicCommand, SIGNAL(gmicFinished(bool, int, QString)), this, SIGNAL(gmicFinished(bool,int,QString))); connect(gmicCommand, SIGNAL(gmicFinished(bool, int, QString)), this, SIGNAL(gmicFinished(bool,int,QString)));
m_progress = gmicCommand->progressPtr(); m_progress = gmicCommand->progressPtr();
...@@ -105,11 +107,16 @@ void KisGmicApplicator::preview() ...@@ -105,11 +107,16 @@ void KisGmicApplicator::preview()
void KisGmicApplicator::cancel() void KisGmicApplicator::cancel()
{ {
dbgPlugins << "Lock!";
m_mutex->lock();
if (m_cancel) if (m_cancel)
{ {
dbgPlugins << "Cancel gmic script"; dbgPlugins << "Cancel gmic script";
*m_cancel = true; *m_cancel = true;
} }
dbgPlugins << "Unlock!";
m_mutex->unlock();
if (m_applicator) if (m_applicator)
{ {
...@@ -155,6 +162,7 @@ void KisGmicApplicator::finish() ...@@ -155,6 +162,7 @@ void KisGmicApplicator::finish()
float KisGmicApplicator::getProgress() const float KisGmicApplicator::getProgress() const
{ {
QMutexLocker locker(m_mutex.data());
if (m_progress) if (m_progress)
{ {
return *m_progress; return *m_progress;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <kis_types.h> #include <kis_types.h>
#include <QThread> #include <QThread>
#include <QMutex>
class KisProcessingApplicator; class KisProcessingApplicator;
...@@ -55,6 +56,7 @@ private: ...@@ -55,6 +56,7 @@ private:
bool m_applicatorStrokeEnded; bool m_applicatorStrokeEnded;
float * m_progress; float * m_progress;
bool * m_cancel; bool * m_cancel;
QSharedPointer<QMutex> m_mutex;
}; };
#endif #endif
......
...@@ -32,7 +32,7 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer< ...@@ -32,7 +32,7 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer<
m_images(images), m_images(images),
m_customCommands(customCommands), m_customCommands(customCommands),
m_firstRedo(true), m_firstRedo(true),
m_progress(new float(-1)), m_progress(new float(-1.0f)),
m_cancel(new bool(false)), m_cancel(new bool(false)),
m_isSuccessfullyDone(false) m_isSuccessfullyDone(false)
{ {
...@@ -40,8 +40,23 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer< ...@@ -40,8 +40,23 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer<
KisGmicCommand::~KisGmicCommand() KisGmicCommand::~KisGmicCommand()
{ {
dbgPlugins << "Destructor: " << this;
if (m_mutex)
{
dbgPlugins << "Lock!";
m_mutex->lock();
}
delete m_cancel; delete m_cancel;
delete m_progress; delete m_progress;
m_cancel = 0;
m_progress = 0;
if (m_mutex)
{
dbgPlugins << "Unlock!";
m_mutex->unlock();
}
} }
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <gmic.h> #include <gmic.h>
#include <QMutex>
class QString; class QString;
class KisGmicCommand : public QObject, public KUndo2Command class KisGmicCommand : public QObject, public KUndo2Command
...@@ -46,6 +48,8 @@ public: ...@@ -46,6 +48,8 @@ public:
/* @return true if gmic failed in redo () */ /* @return true if gmic failed in redo () */
bool isSuccessfullyDone(); bool isSuccessfullyDone();
void setMutex(QSharedPointer<QMutex> mutex){ m_mutex = mutex; }
Q_SIGNALS: Q_SIGNALS:
void gmicFinished(bool successfully, int miliseconds = -1, const QString &msg = QString()); void gmicFinished(bool successfully, int miliseconds = -1, const QString &msg = QString());
...@@ -58,9 +62,10 @@ private: ...@@ -58,9 +62,10 @@ private:
const char * m_customCommands; const char * m_customCommands;
bool m_firstRedo; bool m_firstRedo;
float * const m_progress; float * m_progress;
bool * const m_cancel; // cancels gmic command execution bool * m_cancel; // cancels gmic command execution
bool m_isSuccessfullyDone; bool m_isSuccessfullyDone;
QSharedPointer<QMutex> m_mutex;
}; };
#endif /* __KIS_GMIC_COMMAND_H */ #endif /* __KIS_GMIC_COMMAND_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment