Remove support for Windows XP.
[dcpomatic.git] / src / lib / j2k_encoder.cc
index 431a47e6530e8277961ebc1f5ca0a6b7f24c32c2..64cd3814784306877628794326fdcec462cd88af 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.
 
@@ -44,6 +44,7 @@
 
 using std::list;
 using std::cout;
+using std::exception;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::optional;
@@ -63,14 +64,7 @@ J2KEncoder::J2KEncoder (shared_ptr<const Film> film, shared_ptr<Writer> writer)
 
 J2KEncoder::~J2KEncoder ()
 {
-       try {
-               terminate_threads ();
-       } catch (...) {
-               /* Destructors must not throw exceptions; anything bad
-                  happening now is too late to worry about anyway,
-                  I think.
-               */
-       }
+       terminate_threads ();
 }
 
 void
@@ -115,6 +109,9 @@ J2KEncoder::end ()
 
        terminate_threads ();
 
+       /* Something might have been thrown during terminate_threads */
+       rethrow ();
+
        LOG_GENERAL (N_("Mopping up %1"), _queue.size());
 
        /* The following sequence of events can occur in the above code:
@@ -142,9 +139,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 ();
@@ -181,11 +178,7 @@ J2KEncoder::encode (shared_ptr<PlayerVideo> pv, DCPTime time)
 {
        _waker.nudge ();
 
-       size_t threads = 0;
-       {
-               boost::mutex::scoped_lock threads_lock (_threads_mutex);
-               threads = _threads.size ();
-       }
+       size_t threads = _threads->size();
 
        boost::mutex::scoped_lock queue_lock (_queue_mutex);
 
@@ -246,24 +239,22 @@ J2KEncoder::encode (shared_ptr<PlayerVideo> pv, DCPTime time)
 void
 J2KEncoder::terminate_threads ()
 {
-       boost::mutex::scoped_lock threads_lock (_threads_mutex);
+       boost::this_thread::disable_interruption dis;
 
-       int n = 0;
-       for (list<boost::thread *>::iterator i = _threads.begin(); i != _threads.end(); ++i) {
-               LOG_GENERAL ("Terminating thread %1 of %2", n + 1, _threads.size ());
-               (*i)->interrupt ();
-               DCPOMATIC_ASSERT ((*i)->joinable ());
-               try {
-                       (*i)->join ();
-               } catch (boost::thread_interrupted& e) {
-                       /* This is to be expected */
-               }
-               delete *i;
-               LOG_GENERAL_NC ("Thread terminated");
-               ++n;
+       if (!_threads) {
+               return;
        }
 
-       _threads.clear ();
+       _threads->interrupt_all ();
+       try {
+               _threads->join_all ();
+       } catch (exception& e) {
+               LOG_ERROR ("join() threw an exception: %1", e.what());
+       } catch (...) {
+               LOG_ERROR_NC ("join() threw an exception");
+       }
+
+       _threads.reset ();
 }
 
 void
@@ -377,32 +368,17 @@ void
 J2KEncoder::servers_list_changed ()
 {
        terminate_threads ();
+       _threads.reset (new boost::thread_group());
 
        /* XXX: could re-use threads */
 
-       boost::mutex::scoped_lock lm (_threads_mutex);
-
-#ifdef BOOST_THREAD_PLATFORM_WIN32
-       OSVERSIONINFO info;
-       info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-       GetVersionEx (&info);
-       bool const windows_xp = (info.dwMajorVersion == 5 && info.dwMinorVersion == 1);
-       if (windows_xp) {
-               LOG_GENERAL_NC (N_("Setting thread affinity for Windows XP"));
-       }
-#endif
-
        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> ()));
 #ifdef DCPOMATIC_LINUX
+                       boost::thread* t = _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>()));
                        pthread_setname_np (t->native_handle(), "encode-worker");
-#endif
-                       _threads.push_back (t);
-#ifdef BOOST_THREAD_PLATFORM_WIN32
-                       if (windows_xp) {
-                               SetThreadAffinityMask (t->native_handle(), 1 << i);
-                       }
+#else
+                       _threads->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, optional<EncodeServerDescription>()));
 #endif
                }
        }
@@ -414,9 +390,9 @@ 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->create_thread(boost::bind(&J2KEncoder::encoder_thread, this, i));
                }
        }
 
-       _writer->set_encoder_threads (_threads.size ());
+       _writer->set_encoder_threads (_threads->size());
 }