core/scriptmodel: handle reentrancy in ScriptModel::setValues

This commit is contained in:
outfoxxed committed 2026-08-16 00:22:04 -07:00
1 parent 78672a8405
commit 532a0606ca
3 files changed
+18 -4

No files matched your search

+1
View File
@@ -20,3 +20,4 @@
- Fixed `PwNodePeakMonitor` crashing when sampling a stream with mismatched channels from the node.
- Fixed unsetting `PopupAnchor.item` causing a crash.
- Fixed hiding the last `PanelWindow` on screen causing a crash under X11.
- Fixed crashes when `ScriptModel.values` is set while processing previously set values.
+14 -2
View File
@@ -16,7 +16,7 @@
bool ScriptModel::updateValuesUnique(const QList<QJSValue>& newValues) {
auto anyChanges = false;
this->hasActiveIterators = true;
this->isModifying = true;
this->mValues.reserve(newValues.size());
auto iter = this->mValues.begin();
@@ -158,12 +158,24 @@ bool ScriptModel::updateValuesUnique(const QList<QJSValue>& newValues) {
}
}
this->hasActiveIterators = false;
this->isModifying = false;
if (this->stagedValues.has_value()) {
auto values = *this->stagedValues;
this->stagedValues.reset();
anyChanges |= this->updateValuesUnique(values);
}
return anyChanges;
}
void ScriptModel::setValues(const QList<QJSValue>& newValues) {
// Re-entrant modification waits for the original modification to complete to avoid mishandled duplicates.
if (this->isModifying) {
this->stagedValues = newValues;
return;
}
auto changed = this->updateValuesUnique(newValues);
if (changed) emit this->valuesChanged();
}
+3 -2
View File
@@ -85,7 +85,7 @@ public:
[[nodiscard]] QList<QJSValue> values() const {
auto values = this->mValues;
// If not detached, the QML engine will invalidate iterators in updateValuesUnique.
if (this->hasActiveIterators) values.detach();
if (this->isModifying) values.detach();
return values;
}
@@ -105,7 +105,8 @@ signals:
private:
QList<QJSValue> mValues;
QString cmpKey;
bool hasActiveIterators = false;
bool isModifying = false;
std::optional<QList<QJSValue>> stagedValues;
bool updateValuesUnique(const QList<QJSValue>& newValues);
};