diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2021-10-19 03:47:47 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2021-10-19 05:50:54 +0200 |
commit | 2ef545b487209fb03bc2506b8e9bfa345d0f392b (patch) | |
tree | 7d0a551cdc9962002048b642016be6192eed2651 /options/value.hpp | |
parent | e9a4a44ddebebfde2b1dc5e607336f241821175b (diff) |
options/tie: fix deadlocks
Diffstat (limited to 'options/value.hpp')
-rw-r--r-- | options/value.hpp | 22 |
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); } } |