diff options
| author | Carl Hetherington <cth@carlh.net> | 2017-01-28 00:35:55 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2017-01-28 00:35:55 +0000 |
| commit | f5bc071ddac2355da1d116404cc37f4485e97699 (patch) | |
| tree | 55da5257669b366fac0a6d9d214655f75867543a /src/lib | |
| parent | 861267156da5960260c9a080dce94c0892fd012a (diff) | |
Add priority control buttons to batch converter (#961).
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/job.cc | 33 | ||||
| -rw-r--r-- | src/lib/job.h | 9 | ||||
| -rw-r--r-- | src/lib/job_manager.cc | 69 | ||||
| -rw-r--r-- | src/lib/job_manager.h | 6 |
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; |
