From f5afdd91a5190250ed0916b606652c07a70b2c73 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 10 May 2021 23:42:40 +0200 Subject: [PATCH] Preventing event recursion on different levels. --- src/lay/lay/layApplication.cc | 5 +++++ src/lay/lay/layMainWindow.h | 8 ++++++++ src/tl/tl/tlLog.cc | 15 ++++++++++++--- src/tl/tl/tlLog.h | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index 76a9000cd..31998ed02 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -1486,6 +1486,11 @@ GuiApplication::process_events_impl (QEventLoop::ProcessEventsFlags flags, bool { if (mp_mw) { + // prevent recursive process_events + if (mp_mw->is_busy ()) { + return; + } + if (silent && tl::DeferredMethodScheduler::instance ()) { tl::DeferredMethodScheduler::instance ()->enable (false); } diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index b5e37b283..20397b9f0 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -408,6 +408,14 @@ public: m_busy = bm; } + /** + * @brief Returns true if the application is busy + */ + bool is_busy () const + { + return m_busy; + } + /** * @brief Enable synchronous mode or disable it * diff --git a/src/tl/tl/tlLog.cc b/src/tl/tl/tlLog.cc index bfb5aafc9..1cebcb011 100644 --- a/src/tl/tl/tlLog.cc +++ b/src/tl/tl/tlLog.cc @@ -67,7 +67,7 @@ verbosity () // Channel implementation Channel::Channel () - : m_no_endl (false), m_active (false) + : m_no_endl (false), m_active (false), m_in_yield (false) { // .. nothing else .. } @@ -98,10 +98,19 @@ Channel::release_proxy () end (); m_active = false; m_no_endl = false; + bool in_yield = m_in_yield; + m_in_yield = true; m_lock.unlock (); - // after we have released the lock we give the receivers an opportunity to process events - yield (); + // after we have released the lock we give the receivers an opportunity to process events. Note that we allow only one thread to yield + // at the same time and no recursive yields. + if (! in_yield) { + yield (); + // this should be atomic, but execution reordering may place it before yield(). Hence the lock. + m_lock.lock (); + m_in_yield = false; + m_lock.unlock (); + } } ChannelEndl endl; diff --git a/src/tl/tl/tlLog.h b/src/tl/tl/tlLog.h index b085a14b7..775222c29 100644 --- a/src/tl/tl/tlLog.h +++ b/src/tl/tl/tlLog.h @@ -154,6 +154,7 @@ private: bool m_no_endl; bool m_active; + bool m_in_yield; }; /**