summaryrefslogtreecommitdiffhomepage
path: root/options
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2019-01-16 06:11:48 +0100
committerStanislaw Halik <sthalik@misaki.pl>2019-01-16 07:49:13 +0100
commit07b45ca4578ccaed91f7f3c70e82dc7ffbdf47ab (patch)
tree0904b728158414937919f62714358725f52e7400 /options
parent1e04979c3452d4eac633677876a88f9411a1153d (diff)
spline: fix deadlock, logic error
Tracking rarely deadlocked when saving mappings. Investigating it further also shown how a wrong bundle was used for Accela's splines.
Diffstat (limited to 'options')
-rw-r--r--options/bundle.cpp39
-rw-r--r--options/connector.cpp1
-rw-r--r--options/value.hpp31
3 files changed, 42 insertions, 29 deletions
diff --git a/options/bundle.cpp b/options/bundle.cpp
index 6b7ccce1..dc0f0fcf 100644
--- a/options/bundle.cpp
+++ b/options/bundle.cpp
@@ -13,7 +13,7 @@
#include <cstdlib>
#include <QThread>
-#include <QApplication>
+#include <QCoreApplication>
using namespace options;
using namespace options::globals;
@@ -31,52 +31,51 @@ bundle::~bundle() = default;
void bundle::reload()
{
- if (!group_name.isEmpty())
+ if (group_name.isEmpty())
+ return;
+
{
- QMutexLocker l(&mtx);
+ QMutexLocker l{&mtx};
saved = group(group_name);
transient = saved;
connector::notify_all_values();
- emit reloading();
- emit changed();
}
+
+ emit reloading();
+ emit changed();
}
void bundle::set_all_to_default()
{
- QMutexLocker l(&mtx);
-
- forall([](value_* val) {
- set_value_to_default(val);
- });
+ connector::set_all_to_default_();
}
void bundle::store_kv(const QString& name, const QVariant& new_value)
{
- QMutexLocker l(&mtx);
+ if (group_name.isEmpty())
+ return;
- if (!group_name.isEmpty())
{
- transient.put(name, new_value);
-
mark_ini_modified();
-
+ QMutexLocker l{&mtx};
+ transient.put(name, new_value);
connector::notify_values(name);
- emit changed();
}
+
+ emit changed();
}
QVariant bundle::get_variant(const QString& name) const
{
- QMutexLocker l(&mtx);
+ QMutexLocker l{&mtx};
return transient.get_variant(name);
}
bool bundle::contains(const QString &name) const
{
- QMutexLocker l(&mtx);
+ QMutexLocker l{&mtx};
return transient.contains(name);
}
@@ -89,8 +88,7 @@ void bundle::save()
return;
{
- QMutexLocker l(&mtx);
-
+ QMutexLocker l{&mtx};
saved = transient;
saved.save();
}
@@ -127,7 +125,6 @@ std::shared_ptr<bundler::v> bundler::make_bundle_(const k& key)
QMutexLocker l(&implsgl_mtx);
using iter = decltype(implsgl_data.cbegin());
-
const iter it = implsgl_data.find(key);
if (it != implsgl_data.end())
diff --git a/options/connector.cpp b/options/connector.cpp
index 35d408d5..40c99a82 100644
--- a/options/connector.cpp
+++ b/options/connector.cpp
@@ -17,7 +17,6 @@ connector::~connector() = default;
void connector::on_value_destructed(value_type val)
{
const QString& name = val->name();
-
QMutexLocker l(get_mtx());
const auto it = connected_values.find(name);
diff --git a/options/value.hpp b/options/value.hpp
index 64234ecf..b73b519a 100644
--- a/options/value.hpp
+++ b/options/value.hpp
@@ -46,7 +46,7 @@ class value final : public value_
cc_noinline
t get() const noexcept
{
- if (self_name.isEmpty() || !b->contains(self_name))
+ if (!b->contains(self_name))
return traits::pass_value(def);
QVariant variant = b->get_variant(self_name);
@@ -58,11 +58,8 @@ class value final : public value_
}
cc_noinline
- void store_variant(const QVariant& value) noexcept override
+ void store_variant(QVariant&& value) noexcept override
{
- if (self_name.isEmpty())
- return;
-
if (traits::is_equal(get(), traits::value_from_qvariant(value)))
return;
@@ -72,10 +69,30 @@ class value final : public value_
b->store_kv(self_name, traits::qvariant_from_value(def));
}
+ cc_noinline
+ void store_variant(const QVariant& value) noexcept override
+ {
+ QVariant copy{value};
+ store_variant(std::move(copy));
+ }
+
+ bool is_null() const
+ {
+ return self_name.isEmpty() || b->name().isEmpty();
+ }
+
public:
+ QVariant get_variant() const noexcept override
+ {
+ if (QVariant ret{b->get_variant(self_name)}; ret.isValid() && !ret.isNull())
+ return ret;
+
+ return traits::qvariant_from_value(def);
+ }
+
void notify() const override
{
- if (!self_name.isEmpty())
+ if (!is_null())
emit valueChanged(traits::storage_from_value(get()));
}
@@ -100,7 +117,7 @@ public:
return def;
}
- void set_to_default() override
+ void set_to_default() noexcept override
{
*this = def;
}