Merge master.
[dcpomatic.git] / src / lib / job.cc
index 78a7a75776c8f9463c48b73cfd5b7eceb1be1804..1c66d87d379a7ba8395fa128be4c4aa26876220b 100644 (file)
@@ -38,6 +38,7 @@ using boost::shared_ptr;
  */
 Job::Job (shared_ptr<Film> f)
        : _film (f)
+       , _thread (0)
        , _state (NEW)
        , _start_time (0)
        , _progress_unknown (false)
@@ -52,7 +53,7 @@ Job::start ()
 {
        set_state (RUNNING);
        _start_time = time (0);
-       boost::thread (boost::bind (&Job::run_wrapper, this));
+       _thread = new boost::thread (boost::bind (&Job::run_wrapper, this));
 }
 
 /** A wrapper for the ::run() method to catch exceptions */
@@ -81,6 +82,10 @@ Job::run_wrapper ()
                }
 
                set_error (e.what(), m);
+
+       } catch (boost::thread_interrupted &) {
+
+               set_state (FINISHED_CANCELLED);
                
        } catch (std::exception& e) {
 
@@ -124,7 +129,7 @@ bool
 Job::finished () const
 {
        boost::mutex::scoped_lock lm (_state_mutex);
-       return _state == FINISHED_OK || _state == FINISHED_ERROR;
+       return _state == FINISHED_OK || _state == FINISHED_ERROR || _state == FINISHED_CANCELLED;
 }
 
 /** @return true if the job has finished successfully */
@@ -143,6 +148,13 @@ Job::finished_in_error () const
        return _state == FINISHED_ERROR;
 }
 
+bool
+Job::finished_cancelled () const
+{
+       boost::mutex::scoped_lock lm (_state_mutex);
+       return _state == FINISHED_CANCELLED;
+}
+
 /** Set the state of this job.
  *  @param s New state.
  */
@@ -177,6 +189,7 @@ Job::set_progress (float p)
        boost::mutex::scoped_lock lm (_progress_mutex);
        _progress_unknown = false;
        _stack.back().normalised = p;
+       boost::this_thread::interruption_point ();
 }
 
 /** @return fractional overall progress, or -1 if not known */
@@ -289,6 +302,8 @@ Job::status () const
                s << String::compose (_("OK (ran for %1)"), seconds_to_hms (_ran_for));
        } else if (finished_in_error ()) {
                s << String::compose (_("Error (%1)"), error_summary());
+       } else if (finished_cancelled ()) {
+               s << _("Cancelled");
        }
 
        return s.str ();
@@ -300,3 +315,14 @@ Job::remaining_time () const
 {
        return elapsed_time() / overall_progress() - elapsed_time();
 }
+
+void
+Job::cancel ()
+{
+       if (!_thread) {
+               return;
+       }
+
+       _thread->interrupt ();
+       _thread->join ();
+}