summaryrefslogtreecommitdiff
path: root/libs/ardour/presentation_info.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-01-28 09:57:21 +0100
committerPaul Davis <paul@linuxaudiosystems.com>2017-01-28 09:57:21 +0100
commite998ef5a75c6bdd6a2146acbbe7318069d607117 (patch)
tree1cef8e82943fe5cee9b9757354d8a60559e72145 /libs/ardour/presentation_info.cc
parentc3d0af413a6729c9acfbece7d8215444ec429471 (diff)
fix deadlock in mutex'ed PresentationInfo code
Diffstat (limited to 'libs/ardour/presentation_info.cc')
-rw-r--r--libs/ardour/presentation_info.cc22
1 files changed, 14 insertions, 8 deletions
diff --git a/libs/ardour/presentation_info.cc b/libs/ardour/presentation_info.cc
index 31f595a8c2..64d2a35828 100644
--- a/libs/ardour/presentation_info.cc
+++ b/libs/ardour/presentation_info.cc
@@ -61,14 +61,22 @@ PresentationInfo::suspend_change_signal ()
void
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 (!_pending_static_changes.empty()) {
+ /* atomically grab currently pending flags */
+
+ PropertyChange pc;
+
+ {
+ Glib::Threads::Mutex::Lock lm (static_signal_lock);
+ pc = _pending_static_changes;
+ _pending_static_changes.clear ();
+ }
+
+ if (!pc.empty()) {
std::cerr << "PI change (unsuspended): ";
- for (PropertyChange::const_iterator x = _pending_static_changes.begin(); x != _pending_static_changes.end(); ++x) {
+ for (PropertyChange::const_iterator x = pc.begin(); x != pc.end(); ++x) {
std::cerr << g_quark_to_string (*x) << ',';
}
std::cerr << '\n';
@@ -79,9 +87,7 @@ PresentationInfo::unsuspend_change_signal ()
* they are handling this one.
*/
- Change (_pending_static_changes); /* EMIT SIGNAL */
-
- _pending_static_changes.clear ();
+ Change (pc); /* EMIT SIGNAL */
}
g_atomic_int_add (const_cast<gint*>(&_change_signal_suspended), -1);
@@ -95,9 +101,9 @@ PresentationInfo::send_static_change (const PropertyChange& what_changed)
return;
}
- Glib::Threads::Mutex::Lock lm (static_signal_lock);
if (g_atomic_int_get (&_change_signal_suspended)) {
+ Glib::Threads::Mutex::Lock lm (static_signal_lock);
_pending_static_changes.add (what_changed);
return;
}