Fix deadlock on cancelling jobs. v2.16.21
authorCarl Hetherington <cth@carlh.net>
Mon, 15 Aug 2022 23:38:28 +0000 (01:38 +0200)
committerCarl Hetherington <cth@carlh.net>
Mon, 15 Aug 2022 23:38:36 +0000 (01:38 +0200)
src/tools/dcpomatic.cc

index 6f55b1771b88f2bbbc352520aa7c7deae10005b7..57fad5a0a49ac031ca42365feebe956fdad23493 100644 (file)
@@ -372,7 +372,7 @@ public:
                _film_editor->content_panel()->SelectionChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
                set_title ();
 
-               JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
+               JobManager::instance()->ActiveJobsChanged.connect(boost::bind(&DOMFrame::active_jobs_changed, this));
 
                overall_panel->SetSizer (main_sizer);
 
@@ -1200,6 +1200,15 @@ private:
                ev.Skip ();
        }
 
+       void active_jobs_changed()
+       {
+               /* ActiveJobsChanged can be called while JobManager holds a lock on its mutex, making
+                * the call to JobManager::get() in set_menu_sensitivity() deadlock unless we work around
+                * it by using an idle callback.  This feels quite unpleasant.
+                */
+               signal_manager->when_idle(boost::bind(&DOMFrame::set_menu_sensitivity, this));
+       }
+
        void set_menu_sensitivity ()
        {
                auto jobs = JobManager::instance()->get ();