summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-01-28 00:35:55 +0000
committerCarl Hetherington <cth@carlh.net>2017-01-28 00:35:55 +0000
commitf5bc071ddac2355da1d116404cc37f4485e97699 (patch)
tree55da5257669b366fac0a6d9d214655f75867543a /src/lib
parent861267156da5960260c9a080dce94c0892fd012a (diff)
Add priority control buttons to batch converter (#961).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/job.cc33
-rw-r--r--src/lib/job.h9
-rw-r--r--src/lib/job_manager.cc69
-rw-r--r--src/lib/job_manager.h6
4 files changed, 105 insertions, 12 deletions
diff --git a/src/lib/job.cc b/src/lib/job.cc
index dba21f91c..dacc8bf31 100644
--- a/src/lib/job.cc
+++ b/src/lib/job.cc
@@ -239,10 +239,17 @@ Job::finished_cancelled () const
}
bool
-Job::paused () const
+Job::paused_by_user () const
{
boost::mutex::scoped_lock lm (_state_mutex);
- return _state == PAUSED;
+ return _state == PAUSED_BY_USER;
+}
+
+bool
+Job::paused_by_priority () const
+{
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _state == PAUSED_BY_PRIORITY;
}
/** Set the state of this job.
@@ -287,7 +294,7 @@ Job::check_for_interruption_or_pause ()
boost::this_thread::interruption_point ();
boost::mutex::scoped_lock lm (_state_mutex);
- while (_state == PAUSED) {
+ while (_state == PAUSED_BY_USER || _state == PAUSED_BY_PRIORITY) {
emit (boost::bind (boost::ref (Progress)));
_pause_changed.wait (lm);
}
@@ -450,7 +457,8 @@ Job::json_status () const
return N_("new");
case RUNNING:
return N_("running");
- case PAUSED:
+ case PAUSED_BY_USER:
+ case PAUSED_BY_PRIORITY:
return N_("paused");
case FINISHED_OK:
return N_("finished_ok");
@@ -481,7 +489,7 @@ Job::cancel ()
return;
}
- if (paused ()) {
+ if (paused_by_user() || paused_by_priority()) {
resume ();
}
@@ -493,10 +501,19 @@ Job::cancel ()
}
void
-Job::pause ()
+Job::pause_by_user ()
+{
+ if (running ()) {
+ set_state (PAUSED_BY_USER);
+ _pause_changed.notify_all ();
+ }
+}
+
+void
+Job::pause_by_priority ()
{
if (running ()) {
- set_state (PAUSED);
+ set_state (PAUSED_BY_PRIORITY);
_pause_changed.notify_all ();
}
}
@@ -504,7 +521,7 @@ Job::pause ()
void
Job::resume ()
{
- if (paused ()) {
+ if (paused_by_user() || paused_by_priority()) {
set_state (RUNNING);
_pause_changed.notify_all ();
}
diff --git a/src/lib/job.h b/src/lib/job.h
index 660ddaa13..311f9cc91 100644
--- a/src/lib/job.h
+++ b/src/lib/job.h
@@ -50,7 +50,8 @@ public:
virtual void run () = 0;
void start ();
- void pause ();
+ void pause_by_user ();
+ void pause_by_priority ();
void resume ();
void cancel ();
@@ -60,7 +61,8 @@ public:
bool finished_ok () const;
bool finished_in_error () const;
bool finished_cancelled () const;
- bool paused () const;
+ bool paused_by_user () const;
+ bool paused_by_priority () const;
std::string error_summary () const;
std::string error_details () const;
@@ -94,7 +96,8 @@ protected:
enum State {
NEW, ///< the job hasn't been started yet
RUNNING, ///< the job is running
- PAUSED, ///< the job has been paused
+ PAUSED_BY_USER, ///< the job has been paused
+ PAUSED_BY_PRIORITY, ///< the job has been paused
FINISHED_OK, ///< the job has finished successfully
FINISHED_ERROR, ///< the job has finished in error
FINISHED_CANCELLED ///< the job was cancelled
diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc
index c9924d226..3992e685e 100644
--- a/src/lib/job_manager.cc
+++ b/src/lib/job_manager.cc
@@ -210,3 +210,72 @@ JobManager::analyse_audio (
emit (boost::bind (boost::ref (JobAdded), weak_ptr<Job> (job)));
}
+
+void
+JobManager::increase_priority (shared_ptr<Job> job)
+{
+ bool changed = false;
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ list<shared_ptr<Job> >::iterator last = _jobs.end ();
+ for (list<shared_ptr<Job> >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) {
+ if (*i == job && last != _jobs.end()) {
+ swap (*i, *last);
+ changed = true;
+ break;
+ }
+ last = i;
+ }
+ }
+
+ if (changed) {
+ priority_changed ();
+ }
+}
+
+void
+JobManager::priority_changed ()
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+
+ bool first = true;
+ BOOST_FOREACH (shared_ptr<Job> i, _jobs) {
+ if (first) {
+ if (i->is_new ()) {
+ i->start ();
+ } else if (i->paused_by_priority ()) {
+ i->resume ();
+ }
+ first = false;
+ } else {
+ if (i->running ()) {
+ i->pause_by_priority ();
+ }
+ }
+ }
+ }
+
+ emit (boost::bind (boost::ref (JobsReordered)));
+}
+
+void
+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;
+ }
+ }
+
+ if (changed) {
+ priority_changed ();
+ }
+}
diff --git a/src/lib/job_manager.h b/src/lib/job_manager.h
index c6be2a78e..c623b6ef9 100644
--- a/src/lib/job_manager.h
+++ b/src/lib/job_manager.h
@@ -40,11 +40,12 @@ extern bool wait_for_jobs ();
class JobManager : public Signaller, public boost::noncopyable
{
public:
-
boost::shared_ptr<Job> add (boost::shared_ptr<Job>);
std::list<boost::shared_ptr<Job> > get () const;
bool work_to_do () const;
bool errors () const;
+ void increase_priority (boost::shared_ptr<Job>);
+ void decrease_priority (boost::shared_ptr<Job>);
void analyse_audio (
boost::shared_ptr<const Film> film,
@@ -54,6 +55,7 @@ public:
);
boost::signals2::signal<void (boost::weak_ptr<Job>)> JobAdded;
+ boost::signals2::signal<void ()> JobsReordered;
boost::signals2::signal<void (boost::optional<std::string>, boost::optional<std::string>)> ActiveJobsChanged;
static JobManager* instance ();
@@ -67,8 +69,10 @@ private:
~JobManager ();
void scheduler ();
void start ();
+ void priority_changed ();
mutable boost::mutex _mutex;
+ /** List of jobs in the order that they will be executed */
std::list<boost::shared_ptr<Job> > _jobs;
bool _terminate;