From: Carl Hetherington Date: Thu, 16 Aug 2018 22:14:57 +0000 (+0100) Subject: Add pause/resume to the batch converter (#1248). X-Git-Tag: v2.13.43~22 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=bb990ccc49ee724a8af2ad80bde066374af4b68a Add pause/resume to the batch converter (#1248). Add some missing locking to JobManager::decrease_priority. --- diff --git a/ChangeLog b/ChangeLog index 669719dd2..fd179a68f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2018-08-16 Carl Hetherington + + * Add pause/resume to the batch converter (#1248). + 2018-08-15 Carl Hetherington * Support download of Barco Alchemy, Christie and GDC certificates diff --git a/src/lib/job.cc b/src/lib/job.cc index 06416d1fe..ec6d5d306 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -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 diff --git a/src/lib/job.h b/src/lib/job.h index e5552e49e..d2691a3cb 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -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 (); diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc index 6d651d2ba..535830c0c 100644 --- a/src/lib/job_manager.cc +++ b/src/lib/job_manager.cc @@ -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 i, _jobs) { + if (!_paused) { + BOOST_FOREACH (shared_ptr 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) { bool changed = false; - for (list >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) { - list >::iterator next = i; - ++next; - if (*i == job && next != _jobs.end()) { - swap (*i, *next); - changed = true; - break; + { + boost::mutex::scoped_lock lm (_mutex); + for (list >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) { + list >::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) priority_changed (); } } + +void +JobManager::pause () +{ + boost::mutex::scoped_lock lm (_mutex); + + if (_paused) { + return; + } + + BOOST_FOREACH (shared_ptr 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; +} diff --git a/src/lib/job_manager.h b/src/lib/job_manager.h index a382dd736..aafb7aa67 100644 --- a/src/lib/job_manager.h +++ b/src/lib/job_manager.h @@ -47,6 +47,12 @@ public: bool errors () const; void increase_priority (boost::shared_ptr); void decrease_priority (boost::shared_ptr); + void pause (); + void resume (); + bool paused () const { + boost::mutex::scoped_lock lm (_mutex); + return _paused; + } void analyse_audio ( boost::shared_ptr film, @@ -77,6 +83,8 @@ private: /** List of jobs in the order that they will be executed */ std::list > _jobs; bool _terminate; + bool _paused; + boost::shared_ptr _paused_job; boost::optional _last_active_job; boost::thread* _scheduler; diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc index 6d4490ad7..ac57baf4b 100644 --- a/src/tools/dcpomatic_batch.cc +++ b/src/tools/dcpomatic_batch.cc @@ -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 #include @@ -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[] = {