Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit ba7aecfe authored by David Edmundson's avatar David Edmundson

[scripting] Avoid threading issues when loading from a file

Summary:
KWin::Script::loadScriptFromFile ran in it's own thread and accessed
member variables of KWin::Script without any guards.

Potentially script could be destroyed whilst the file is loading.

Rather than adding mutexes everywhere, this patch scopes the QFile
object to be local to the threaded function making it independent.

BUG: 403038

Test Plan: Ran a script from a file

Reviewers: #kwin, graesslin

Reviewed By: #kwin, graesslin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18126
parent fbe21917
......@@ -231,9 +231,9 @@ KWin::AbstractScript::AbstractScript(int id, QString scriptName, QString pluginN
: QObject(parent)
, m_scriptId(id)
, m_pluginName(pluginName)
, m_fileName(scriptName)
, m_running(false)
{
m_scriptFile.setFileName(scriptName);
if (m_pluginName.isNull()) {
m_pluginName = scriptName;
}
......@@ -255,7 +255,7 @@ void KWin::AbstractScript::stop()
void KWin::AbstractScript::printMessage(const QString &message)
{
qCDebug(KWIN_SCRIPTING) << scriptFile().fileName() << ":" << message;
qCDebug(KWIN_SCRIPTING) << fileName() << ":" << message;
emit print(message);
}
......@@ -468,16 +468,16 @@ void KWin::Script::run()
m_starting = true;
QFutureWatcher<QByteArray> *watcher = new QFutureWatcher<QByteArray>(this);
connect(watcher, SIGNAL(finished()), SLOT(slotScriptLoadedFromFile()));
watcher->setFuture(QtConcurrent::run(this, &KWin::Script::loadScriptFromFile));
watcher->setFuture(QtConcurrent::run(this, &KWin::Script::loadScriptFromFile, fileName()));
}
QByteArray KWin::Script::loadScriptFromFile()
QByteArray KWin::Script::loadScriptFromFile(const QString &fileName)
{
if (!scriptFile().open(QIODevice::ReadOnly)) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
return QByteArray();
}
QByteArray result(scriptFile().readAll());
scriptFile().close();
QByteArray result(file.readAll());
return result;
}
......@@ -591,7 +591,7 @@ void KWin::DeclarativeScript::run()
return;
}
m_component->loadUrl(QUrl::fromLocalFile(scriptFile().fileName()));
m_component->loadUrl(QUrl::fromLocalFile(fileName()));
if (m_component->isLoading()) {
connect(m_component, &QQmlComponent::statusChanged, this, &DeclarativeScript::createComponent);
} else {
......
......@@ -60,7 +60,7 @@ public:
AbstractScript(int id, QString scriptName, QString pluginName, QObject *parent = nullptr);
~AbstractScript();
QString fileName() const {
return m_scriptFile.fileName();
return m_fileName;
}
const QString &pluginName() {
return m_pluginName;
......@@ -153,9 +153,6 @@ Q_SIGNALS:
void runningChanged(bool);
protected:
QFile &scriptFile() {
return m_scriptFile;
}
bool running() const {
return m_running;
}
......@@ -204,7 +201,7 @@ private:
**/
QAction *createMenu(const QString &title, QScriptValue &items, QMenu *parent);
int m_scriptId;
QFile m_scriptFile;
QString m_fileName;
QString m_pluginName;
bool m_running;
QHash<QAction*, QScriptValue> m_shortcutCallbacks;
......@@ -255,7 +252,7 @@ private:
* Read the script from file into a byte array.
* If file cannot be read an empty byte array is returned.
**/
QByteArray loadScriptFromFile();
QByteArray loadScriptFromFile(const QString &fileName);
QScriptEngine *m_engine;
bool m_starting;
QScopedPointer<ScriptUnloaderAgent> m_agent;
......
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