13
0

improved (as in "correct") deadlock fix for PresentationInfo::Change

This commit is contained in:
Paul Davis 2017-01-28 11:10:18 +01:00
parent e998ef5a75
commit 5e76d8537b

View File

@ -61,37 +61,31 @@ PresentationInfo::suspend_change_signal ()
void void
PresentationInfo::unsuspend_change_signal () PresentationInfo::unsuspend_change_signal ()
{ {
Glib::Threads::Mutex::Lock lm (static_signal_lock);
if (g_atomic_int_get (const_cast<gint*> (&_change_signal_suspended)) == 1) { if (g_atomic_int_get (const_cast<gint*> (&_change_signal_suspended)) == 1) {
/* atomically grab currently pending flags */ /* atomically grab currently pending flags */
PropertyChange pc; PropertyChange pc = _pending_static_changes;
_pending_static_changes.clear ();
{
Glib::Threads::Mutex::Lock lm (static_signal_lock);
pc = _pending_static_changes;
_pending_static_changes.clear ();
}
if (!pc.empty()) { if (!pc.empty()) {
std::cerr << "PI change (unsuspended): "; /* emit the signal with further emissions still blocked
for (PropertyChange::const_iterator x = pc.begin(); x != pc.end(); ++x) { * by _change_signal_suspended, but not by the lock.
std::cerr << g_quark_to_string (*x) << ','; *
} * This means that if the handlers modify other PI
std::cerr << '\n'; * states, the signal for that won't be sent while they
* are handling the current signal.
/* emit the signal with further emissions still
* blocked, so that if the handlers modify other PI
* states, the signal for that won't be sent while
* they are handling this one.
*/ */
lm.release ();
Change (pc); /* EMIT SIGNAL */ Change (pc); /* EMIT SIGNAL */
lm.acquire ();
} }
g_atomic_int_add (const_cast<gint*>(&_change_signal_suspended), -1);
} }
g_atomic_int_add (const_cast<gint*>(&_change_signal_suspended), -1);
} }
void void