summaryrefslogtreecommitdiffhomepage
path: root/options/value.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2021-10-19 03:47:47 +0200
committerStanislaw Halik <sthalik@misaki.pl>2021-10-19 05:50:54 +0200
commit2ef545b487209fb03bc2506b8e9bfa345d0f392b (patch)
tree7d0a551cdc9962002048b642016be6192eed2651 /options/value.hpp
parente9a4a44ddebebfde2b1dc5e607336f241821175b (diff)
options/tie: fix deadlocks
Diffstat (limited to 'options/value.hpp')
-rw-r--r--options/value.hpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/options/value.hpp b/options/value.hpp
index 10903b19..849611d3 100644
--- a/options/value.hpp
+++ b/options/value.hpp
@@ -39,7 +39,9 @@ template<typename t>
class value final : public value_
{
static_assert(std::is_same_v<t, remove_cvref_t<t>>);
+ mutable QMutex mtx;
const t def;
+ mutable t cached_value = def;
using traits = detail::value_traits<t>;
never_inline
@@ -95,10 +97,24 @@ public:
never_inline
void notify() const override
{
- if (!is_null())
- {
+ if (is_null())
+ return;
+
+ auto x = get();
+
+ bool b = progn(
+ QMutexLocker l(&mtx);
+ if (!traits::is_equal(x, cached_value))
+ {
+ cached_value = x;
+ return true;
+ }
+ return false;
+ );
+
+ if (b) {
maybe_trace(true);
- emit valueChanged(traits::storage_from_value(get()));
+ emit valueChanged(traits::storage_from_value(x));
maybe_trace(false);
}
}