Add pause/resume to the batch converter (#1248).
authorCarl Hetherington <cth@carlh.net>
Thu, 16 Aug 2018 22:14:57 +0000 (23:14 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 16 Aug 2018 22:14:57 +0000 (23:14 +0100)
Add some missing locking to JobManager::decrease_priority.

ChangeLog
src/lib/job.cc
src/lib/job.h
src/lib/job_manager.cc
src/lib/job_manager.h
src/tools/dcpomatic_batch.cc

index 669719dd2ec002d56a2e57325c2e0286a289b6d4..fd179a68fd13dddc057732728b64322195cad3d8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-08-16  Carl Hetherington  <cth@carlh.net>
+
+       * Add pause/resume to the batch converter (#1248).
+
 2018-08-15  Carl Hetherington  <cth@carlh.net>
 
        * Support download of Barco Alchemy, Christie and GDC certificates
index 06416d1fe014b3e55a810c7f0dc89392486791bb..ec6d5d306e21e5c5bbe50834d50fee05d4fbee24 100644 (file)
@@ -519,13 +519,27 @@ Job::cancel ()
        _thread = 0;
 }
 
-void
+/** @return true if the job was paused, false if it was not running */
+bool
 Job::pause_by_user ()
 {
-       if (running ()) {
-               set_state (PAUSED_BY_USER);
+       bool paused = false;
+       {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               /* We can set _state here directly because we have a lock and we aren't
+                  setting the job to FINISHED_*
+               */
+               if (_state == RUNNING) {
+                       paused = true;
+                       _state = PAUSED_BY_USER;
+               }
+       }
+
+       if (paused) {
                _pause_changed.notify_all ();
        }
+
+       return paused;
 }
 
 void
index e5552e49ea8f63acec13443fccf29cc3d6f6b7a9..d2691a3cbcc66e677400e914bcdbebdf2307ee1a 100644 (file)
@@ -50,7 +50,7 @@ public:
        virtual void run () = 0;
 
        void start ();
-       void pause_by_user ();
+       bool pause_by_user ();
        void pause_by_priority ();
        void resume ();
        void cancel ();
index 6d651d2ba1d51adc531efc64b51c6c5f88002d31..535830c0c43cc77cb42263f8af9f3e8164484251 100644 (file)
@@ -44,6 +44,7 @@ JobManager* JobManager::_instance = 0;
 
 JobManager::JobManager ()
        : _terminate (false)
+       , _paused (false)
        , _scheduler (0)
 {
 
@@ -150,21 +151,23 @@ JobManager::scheduler ()
                                return;
                        }
 
-                       BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+                       if (!_paused) {
+                               BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
 
-                               if (!i->finished ()) {
-                                       active_job = i->json_name ();
-                               }
+                                       if (!i->finished ()) {
+                                               active_job = i->json_name ();
+                                       }
 
-                               if (i->running ()) {
-                                       /* Something is already happening */
-                                       break;
-                               }
+                                       if (i->running ()) {
+                                               /* Something is already happening */
+                                               break;
+                                       }
 
-                               if (i->is_new()) {
-                                       i->start ();
-                                       /* Only start one job at once */
-                                       break;
+                                       if (i->is_new()) {
+                                               i->start ();
+                                               /* Only start one job at once */
+                                               break;
+                                       }
                                }
                        }
                }
@@ -284,13 +287,16 @@ JobManager::decrease_priority (shared_ptr<Job> job)
 {
        bool changed = false;
 
-       for (list<shared_ptr<Job> >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) {
-               list<shared_ptr<Job> >::iterator next = i;
-               ++next;
-               if (*i == job && next != _jobs.end()) {
-                       swap (*i, *next);
-                       changed = true;
-                       break;
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               for (list<shared_ptr<Job> >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) {
+                       list<shared_ptr<Job> >::iterator next = i;
+                       ++next;
+                       if (*i == job && next != _jobs.end()) {
+                               swap (*i, *next);
+                               changed = true;
+                               break;
+                       }
                }
        }
 
@@ -298,3 +304,37 @@ JobManager::decrease_priority (shared_ptr<Job> job)
                priority_changed ();
        }
 }
+
+void
+JobManager::pause ()
+{
+       boost::mutex::scoped_lock lm (_mutex);
+
+       if (_paused) {
+               return;
+       }
+
+       BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+               if (i->pause_by_user()) {
+                       _paused_job = i;
+               }
+       }
+
+       _paused = true;
+}
+
+void
+JobManager::resume ()
+{
+       boost::mutex::scoped_lock lm (_mutex);
+       if (!_paused) {
+               return;
+       }
+
+       if (_paused_job) {
+               _paused_job->resume ();
+       }
+
+       _paused_job.reset ();
+       _paused = false;
+}
index a382dd7363732cc4ddd20fad782005bd438ea2ff..aafb7aa67aa8609ce8214ef2e500cbc6e62580af 100644 (file)
@@ -47,6 +47,12 @@ public:
        bool errors () const;
        void increase_priority (boost::shared_ptr<Job>);
        void decrease_priority (boost::shared_ptr<Job>);
+       void pause ();
+       void resume ();
+       bool paused () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _paused;
+       }
 
        void analyse_audio (
                boost::shared_ptr<const Film> film,
@@ -77,6 +83,8 @@ private:
        /** List of jobs in the order that they will be executed */
        std::list<boost::shared_ptr<Job> > _jobs;
        bool _terminate;
+       bool _paused;
+       boost::shared_ptr<Job> _paused_job;
 
        boost::optional<std::string> _last_active_job;
        boost::thread* _scheduler;
index 6d4490ad7bb36a9fc616e3494eb8f2c29d188287..ac57baf4bd83bd9d505fd7510f41cdd512272ceb 100644 (file)
@@ -30,6 +30,7 @@
 #include "lib/util.h"
 #include "lib/film.h"
 #include "lib/job_manager.h"
+#include "lib/job.h"
 #include "lib/dcpomatic_socket.h"
 #include <wx/aboutdlg.h>
 #include <wx/stdpaths.h>
@@ -121,6 +122,14 @@ public:
                wxButton* add = new wxButton (panel, wxID_ANY, _("Add Film..."));
                add->Bind (wxEVT_BUTTON, boost::bind (&DOMFrame::add_film, this));
                buttons->Add (add, 1, wxALL, 6);
+               _pause = new wxButton (panel, wxID_ANY, _("Pause"));
+               _pause->Bind (wxEVT_BUTTON, boost::bind(&DOMFrame::pause, this));
+               buttons->Add (_pause, 1, wxALL, 6);
+               _resume = new wxButton (panel, wxID_ANY, _("Resume"));
+               _resume->Bind (wxEVT_BUTTON, boost::bind(&DOMFrame::resume, this));
+               buttons->Add (_resume, 1, wxALL, 6);
+
+               setup_sensitivity ();
 
                _sizer->Add (buttons, 0, wxALL, 6);
 
@@ -130,6 +139,24 @@ public:
                Bind (wxEVT_SIZE, boost::bind (&DOMFrame::sized, this, _1));
        }
 
+       void setup_sensitivity ()
+       {
+               _pause->Enable (!JobManager::instance()->paused());
+               _resume->Enable (JobManager::instance()->paused());
+       }
+
+       void pause ()
+       {
+               JobManager::instance()->pause ();
+               setup_sensitivity ();
+       }
+
+       void resume ()
+       {
+               JobManager::instance()->resume ();
+               setup_sensitivity ();
+       }
+
        void start_job (boost::filesystem::path path)
        {
                try {
@@ -274,6 +301,8 @@ private:
        wxSizer* _sizer;
        wxPreferencesEditor* _config_dialog;
        ServersListDialog* _servers_list_dialog;
+       wxButton* _pause;
+       wxButton* _resume;
 };
 
 static const wxCmdLineEntryDesc command_line_description[] = {