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 @@
KisGmicApplicator::KisGmicApplicator():m_applicator(0),m_applicatorStrokeEnded(false),m_progress(0),m_cancel(0)
{
m_mutex = QSharedPointer<QMutex>(new QMutex());
}
KisGmicApplicator::~KisGmicApplicator()
......@@ -89,6 +90,7 @@ void KisGmicApplicator::preview()
// apply gmic filters to provided layers
const char * customCommands = m_customCommands.isNull() ? 0 : m_customCommands.constData();
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)));
m_progress = gmicCommand->progressPtr();
......@@ -105,11 +107,16 @@ void KisGmicApplicator::preview()
void KisGmicApplicator::cancel()
{
dbgPlugins << "Lock!";
m_mutex->lock();
if (m_cancel)
{
dbgPlugins << "Cancel gmic script";
*m_cancel = true;
}
dbgPlugins << "Unlock!";
m_mutex->unlock();
if (m_applicator)
{
......@@ -155,6 +162,7 @@ void KisGmicApplicator::finish()
float KisGmicApplicator::getProgress() const
{
QMutexLocker locker(m_mutex.data());
if (m_progress)
{
return *m_progress;
......
......@@ -23,6 +23,7 @@
#include <kis_types.h>
#include <QThread>
#include <QMutex>
class KisProcessingApplicator;
......@@ -55,6 +56,7 @@ private:
bool m_applicatorStrokeEnded;
float * m_progress;
bool * m_cancel;
QSharedPointer<QMutex> m_mutex;
};
#endif
......
......@@ -32,7 +32,7 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer<
m_images(images),
m_customCommands(customCommands),
m_firstRedo(true),
m_progress(new float(-1)),
m_progress(new float(-1.0f)),
m_cancel(new bool(false)),
m_isSuccessfullyDone(false)
{
......@@ -40,8 +40,23 @@ KisGmicCommand::KisGmicCommand(const QString &gmicCommandString, QSharedPointer<
KisGmicCommand::~KisGmicCommand()
{
dbgPlugins << "Destructor: " << this;
if (m_mutex)
{
dbgPlugins << "Lock!";
m_mutex->lock();
}
delete m_cancel;
delete m_progress;
m_cancel = 0;
m_progress = 0;
if (m_mutex)
{
dbgPlugins << "Unlock!";
m_mutex->unlock();
}
}
......
......@@ -28,6 +28,8 @@
#include <gmic.h>
#include <QMutex>
class QString;
class KisGmicCommand : public QObject, public KUndo2Command
......@@ -46,6 +48,8 @@ public:
/* @return true if gmic failed in redo () */
bool isSuccessfullyDone();
void setMutex(QSharedPointer<QMutex> mutex){ m_mutex = mutex; }
Q_SIGNALS:
void gmicFinished(bool successfully, int miliseconds = -1, const QString &msg = QString());
......@@ -58,9 +62,10 @@ private:
const char * m_customCommands;
bool m_firstRedo;
float * const m_progress;
bool * const m_cancel; // cancels gmic command execution
float * m_progress;
bool * m_cancel; // cancels gmic command execution
bool m_isSuccessfullyDone;
QSharedPointer<QMutex> m_mutex;
};
#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