Merge branch 'v2.15.x' of ssh://git.carlh.net/home/carl/git/dcpomatic into v2.15.x
[dcpomatic.git] / src / lib / j2k_encoder.cc
index 94728d6a9e6acccbe5839e4acc0c73d3d1b09530..96b5b86e78867b99d0cffc3414d1f458c7fac22c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 using std::list;
 using std::cout;
+using std::exception;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::optional;
 using dcp::Data;
+using namespace dcpomatic;
 
 /** @param film Film that we are encoding.
  *  @param writer Writer that we are using.
@@ -141,9 +143,9 @@ J2KEncoder::end ()
 }
 
 /** @return an estimate of the current number of frames we are encoding per second,
- *  or 0 if not known.
+ *  if known.
  */
-float
+optional<float>
 J2KEncoder::current_encoding_rate () const
 {
        return _history.rate ();
@@ -248,16 +250,17 @@ J2KEncoder::terminate_threads ()
        boost::mutex::scoped_lock threads_lock (_threads_mutex);
 
        int n = 0;
-       for (list<boost::thread *>::iterator i = _threads.begin(); i != _threads.end(); ++i) {
+       for (list<boost::thread>::iterator i = _threads.begin(); i != _threads.end(); ++i) {
+               /* Be careful not to throw in here otherwise _threads will not be clear()ed */
                LOG_GENERAL ("Terminating thread %1 of %2", n + 1, _threads.size ());
-               (*i)->interrupt ();
-               DCPOMATIC_ASSERT ((*i)->joinable ());
+               i->interrupt ();
                try {
-                       (*i)->join ();
-               } catch (boost::thread_interrupted& e) {
-                       /* This is to be expected */
+                       i->join ();
+               } catch (exception& e) {
+                       LOG_ERROR ("join() threw an exception: %1", e.what());
+               } catch (...) {
+                       LOG_ERROR_NC ("join() threw an exception");
                }
-               delete *i;
                LOG_GENERAL_NC ("Thread terminated");
                ++n;
        }
@@ -393,14 +396,13 @@ J2KEncoder::servers_list_changed ()
 
        if (!Config::instance()->only_servers_encode ()) {
                for (int i = 0; i < Config::instance()->master_encoding_threads (); ++i) {
-                       boost::thread* t = new boost::thread (boost::bind (&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription> ()));
+                       _threads.push_back (boost::thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>())));
 #ifdef DCPOMATIC_LINUX
-                       pthread_setname_np (t->native_handle(), "encode-worker");
+                       pthread_setname_np (_threads.back().native_handle(), "encode-worker");
 #endif
-                       _threads.push_back (t);
 #ifdef BOOST_THREAD_PLATFORM_WIN32
                        if (windows_xp) {
-                               SetThreadAffinityMask (t->native_handle(), 1 << i);
+                               SetThreadAffinityMask (_threads.back().native_handle(), 1 << i);
                        }
 #endif
                }
@@ -413,7 +415,7 @@ J2KEncoder::servers_list_changed ()
 
                LOG_GENERAL (N_("Adding %1 worker threads for remote %2"), i.threads(), i.host_name ());
                for (int j = 0; j < i.threads(); ++j) {
-                       _threads.push_back (new boost::thread (boost::bind (&J2KEncoder::encoder_thread, this, i)));
+                       _threads.push_back (boost::thread(boost::bind(&J2KEncoder::encoder_thread, this, i)));
                }
        }