fix crashes due to glib ignored EDEADLK.
authorRobin Gareus <robin@gareus.org>
Sun, 11 Oct 2015 23:54:44 +0000 (01:54 +0200)
committerRobin Gareus <robin@gareus.org>
Mon, 12 Oct 2015 00:11:04 +0000 (02:11 +0200)
Taking a readlock after a writelock in the same thread should result
in a deadlock, yet pthread on Linux returns EDEADLK and continues.
glib-2.42.0 ignores EDEADLK and assumes the lock was taken. Releasing
the lock later causes issues: "Calling g_rw_lock_writer_unlock() on a
lock that is not held by the current thread leads to undefined behaviour."

The issue at hand:
 AudioStreamView::redisplay_track()
 -> foreach_region()                       #<< WriteLock
 -> add_region_view()
 ...
 -> AudioRegionView::create_one_wave()
 -> RegionView::update_coverage_frames
 -> Playlist::top_unmuted_region_at()      #<< ReadLock

All current users of Playlist::foreach_region() are in the GUI
and AFAICT read-only (display regions, update visuals)

libs/ardour/playlist.cc

index 959b4884a347cd9812f8acd8f47ba151fabf5a05..0e58b4b622dfe7eda5fff483e1e0567cc0063171 100644 (file)
@@ -2841,7 +2841,7 @@ Playlist::update_after_tempo_map_change ()
 void
 Playlist::foreach_region (boost::function<void(boost::shared_ptr<Region>)> s)
 {
-       RegionWriteLock rl (this, false);
+       RegionReadLock rl (this);
        for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
                s (*i);
        }