Preventing event recursion on different levels.

This commit is contained in:
Matthias Koefferlein 2021-05-10 23:42:40 +02:00
parent 0051d83026
commit f5afdd91a5
4 changed files with 26 additions and 3 deletions

View File

@ -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);
}

View File

@ -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
*

View File

@ -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;

View File

@ -154,6 +154,7 @@ private:
bool m_no_endl;
bool m_active;
bool m_in_yield;
};
/**