diff options
| author | Carl Hetherington <cth@carlh.net> | 2024-05-08 01:53:50 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2024-05-08 01:53:50 +0200 |
| commit | 6b2119dcd16c43fd681feace00d4e10f464bb9b7 (patch) | |
| tree | 50ac586ce4aac6d85c98084ddccd47d4c61ed315 /src/lib | |
| parent | 29f773b4871511a686054bfcd4d769c3707907f6 (diff) | |
| parent | 32d04ddb5c583938f470ed74bda8a50cc2ec9960 (diff) | |
Merge remote-tracking branch 'origin/main' into v2.17.x
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/j2k_encoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/writer.cc | 21 | ||||
| -rw-r--r-- | src/lib/writer.h | 5 |
3 files changed, 38 insertions, 0 deletions
diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index 094e104ef..0b50bcd5a 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -108,6 +108,16 @@ J2KEncoder::~J2KEncoder () { _server_found_connection.disconnect(); + /* One of our encoder threads may be waiting on Writer::write() to return, if that method + * is blocked with the writer queue full waiting for _full_condition. In that case, the + * attempt to terminate the encoder threads below (in terminate_threads()) will fail because + * the encoder thread waiting for ::write() will have interruption disabled. + * + * To work around that, make the writer into a zombie to unblock any pending write()s and + * not block on any future ones. + */ + _writer.zombify(); + terminate_threads(); #ifdef DCPOMATIC_GROK @@ -153,6 +163,8 @@ J2KEncoder::pause() } return; + /* XXX; the same problem may occur here as in the destructor, perhaps? */ + terminate_threads (); /* Something might have been thrown during terminate_threads */ diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 3dd22718f..c0b083ff0 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -146,6 +146,10 @@ Writer::write (shared_ptr<const Data> encoded, Frame frame, Eyes eyes) { boost::mutex::scoped_lock lock (_state_mutex); + if (_zombie) { + return; + } + while (_queued_full_in_memory > _maximum_frames_in_memory) { /* There are too many full frames in memory; wake the main writer thread and wait until it sorts everything out */ @@ -382,6 +386,9 @@ try while (true) { boost::mutex::scoped_lock lock (_state_mutex); + if (_zombie) { + return; + } while (true) { @@ -1047,3 +1054,17 @@ Writer::write_hanging_text (ReelWriter& reel) } _hanging_texts = new_hanging_texts; } + + +/** Set the writer so that it has no queue and drops any pending or future requests to write images */ +void +Writer::zombify() +{ + boost::mutex::scoped_lock lock(_state_mutex); + + _queue.clear(); + _queued_full_in_memory = 0; + _zombie = true; + _full_condition.notify_all(); +} + diff --git a/src/lib/writer.h b/src/lib/writer.h index 1dd88d8a9..f9ec0b88c 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -35,6 +35,7 @@ #include "font_id_map.h" #include "player_text.h" #include "text_type.h" +#include "types.h" #include "weak_film.h" #include <dcp/atmos_frame.h> #include <dcp/frame_info.h> @@ -129,6 +130,8 @@ public: void set_encoder_threads (int threads); + void zombify(); + private: friend struct ::writer_disambiguate_font_ids1; friend struct ::writer_disambiguate_font_ids2; @@ -231,6 +234,8 @@ private: }; std::vector<HangingText> _hanging_texts; + + bool _zombie = false; }; |
