Basic attempt to catch exceptions in the writer thread and pass them safely back...
authorCarl Hetherington <cth@carlh.net>
Mon, 11 Feb 2013 00:18:40 +0000 (00:18 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 11 Feb 2013 00:18:40 +0000 (00:18 +0000)
src/lib/encoder.cc
src/lib/exceptions.h
src/lib/writer.cc
src/lib/writer.h

index 0c810d12c6aaf88a65e8782d9e0d389e2c4581cc..d64622cbaa711b1dd046796e97e0318ad1b1bc21 100644 (file)
@@ -251,6 +251,10 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
                return;
        }
 
+       if (_writer->thrown ()) {
+               _writer->rethrow ();
+       }
+
        if (_writer->can_fake_write (_video_frames_out)) {
                _writer->fake_write (_video_frames_out);
                _have_a_real_frame = false;
index bf8e85f0bdfb7d939f76b90ad41c4571361bd874..e757d25069c9182455c5185aeb2183664c2c7a17 100644 (file)
@@ -17,6 +17,9 @@
 
 */
 
+#ifndef DVDOMATIC_EXCEPTIONS_H
+#define DVDOMATIC_EXCEPTIONS_H
+
 /** @file  src/exceptions.h
  *  @brief Our exceptions.
  */
@@ -24,6 +27,8 @@
 #include <stdexcept>
 #include <sstream>
 #include <cstring>
+#include <boost/exception/all.hpp>
+#include <boost/thread.hpp>
 
 /** @class StringError
  *  @brief A parent class for exceptions using messages held in a std::string
@@ -224,3 +229,30 @@ public:
                : StringError (s)
        {}
 };
+
+class ExceptionStore
+{
+public:
+       bool thrown () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _exception;
+       }
+       
+       void rethrow () {
+               boost::mutex::scoped_lock lm (_mutex);
+               boost::rethrow_exception (_exception);
+       }
+
+protected:     
+       
+       void store_current () {
+               boost::mutex::scoped_lock lm (_mutex);
+               _exception = boost::current_exception ();
+       }
+
+private:
+       boost::exception_ptr _exception;
+       mutable boost::mutex _mutex;
+};
+
+#endif
index 1df8a430102c454376e06ac01865ebd86d9dac5e..8a09f254b775716a8cbdb01886b42a0ec5fb2aff 100644 (file)
@@ -85,7 +85,7 @@ Writer::Writer (shared_ptr<Film> f)
 
                _sound_asset_writer = _sound_asset->start_write ();
        }
-       
+
        _thread = new boost::thread (boost::bind (&Writer::thread, this));
 }
 
@@ -130,6 +130,7 @@ Writer::write (shared_ptr<const AudioBuffers> audio)
 
 void
 Writer::thread ()
+try
 {
        while (1)
        {
@@ -221,7 +222,10 @@ Writer::thread ()
                        --_queued_full_in_memory;
                }
        }
-
+}
+catch (...)
+{
+       store_current ();
 }
 
 void
@@ -237,6 +241,10 @@ Writer::finish ()
        lock.unlock ();
 
        _thread->join ();
+       if (thrown ()) {
+               rethrow ();
+       }
+       
        delete _thread;
        _thread = 0;
 
@@ -361,7 +369,6 @@ Writer::can_fake_write (int frame) const
        return (frame != 0 && frame < _first_nonexistant_frame);
 }
 
-
 bool
 operator< (QueueItem const & a, QueueItem const & b)
 {
index cee20acb952f349c64467af3ce72a32b50852f52..beb16c7b9107da1972bcbd5f92a2dc07d3b1b701 100644 (file)
@@ -21,6 +21,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/thread.hpp>
 #include <boost/thread/condition.hpp>
+#include "exceptions.h"
 
 class Film;
 class EncodedData;
@@ -59,7 +60,7 @@ public:
 bool operator< (QueueItem const & a, QueueItem const & b);
 bool operator== (QueueItem const & a, QueueItem const & b);
 
-class Writer
+class Writer : public ExceptionStore
 {
 public:
        Writer (boost::shared_ptr<Film>);
@@ -113,7 +114,7 @@ private:
            due to the limit of frames to be held in memory.
        */
        int _pushed_to_disk;
-
+       
        boost::shared_ptr<libdcp::MonoPictureAsset> _picture_asset;
        boost::shared_ptr<libdcp::MonoPictureAssetWriter> _picture_asset_writer;
        boost::shared_ptr<libdcp::SoundAsset> _sound_asset;