summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-08-16 23:14:57 +0100
committerCarl Hetherington <cth@carlh.net>2018-08-16 23:14:57 +0100
commitbb990ccc49ee724a8af2ad80bde066374af4b68a (patch)
tree4893842f188db4f268def9a2a518bc7858a099b0 /src
parent773346b1518c68dc7533b381a90e77ae276ae6bc (diff)
Add pause/resume to the batch converter (#1248).
Add some missing locking to JobManager::decrease_priority.
Diffstat (limited to 'src')
-rw-r--r--src/lib/job.cc20
-rw-r--r--src/lib/job.h2
-rw-r--r--src/lib/job_manager.cc78
-rw-r--r--src/lib/job_manager.h8
-rw-r--r--src/tools/dcpomatic_batch.cc29
5 files changed, 114 insertions, 23 deletions
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<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;
+}
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<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;
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 <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[] = {