From beea3beacba34c11b6b73323f4c3c8590a9aa73e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 00:18:40 +0000 Subject: Basic attempt to catch exceptions in the writer thread and pass them safely back to the GUI. --- src/lib/encoder.cc | 4 ++++ src/lib/exceptions.h | 32 ++++++++++++++++++++++++++++++++ src/lib/writer.cc | 13 ++++++++++--- src/lib/writer.h | 5 +++-- 4 files changed, 49 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 0c810d12c..d64622cba 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -251,6 +251,10 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrthrown ()) { + _writer->rethrow (); + } + if (_writer->can_fake_write (_video_frames_out)) { _writer->fake_write (_video_frames_out); _have_a_real_frame = false; diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index bf8e85f0b..e757d2506 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -17,6 +17,9 @@ */ +#ifndef DVDOMATIC_EXCEPTIONS_H +#define DVDOMATIC_EXCEPTIONS_H + /** @file src/exceptions.h * @brief Our exceptions. */ @@ -24,6 +27,8 @@ #include #include #include +#include +#include /** @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 diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 1df8a4301..8a09f254b 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -85,7 +85,7 @@ Writer::Writer (shared_ptr 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 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) { diff --git a/src/lib/writer.h b/src/lib/writer.h index cee20acb9..beb16c7b9 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -21,6 +21,7 @@ #include #include #include +#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); @@ -113,7 +114,7 @@ private: due to the limit of frames to be held in memory. */ int _pushed_to_disk; - + boost::shared_ptr _picture_asset; boost::shared_ptr _picture_asset_writer; boost::shared_ptr _sound_asset; -- cgit v1.2.3