From f9ab63ab6d2e7eb4b997790e5ca04b38e0ac3f7a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 18 Dec 2024 00:17:05 +0100 Subject: Fix hang when encoding with GPU enabled but not working. --- src/lib/grok_j2k_encoder_thread.cc | 2 ++ src/lib/j2k_encoder.cc | 20 +++++++++++++------- test/j2k_encode_threading_test.cc | 31 +++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/lib/grok_j2k_encoder_thread.cc b/src/lib/grok_j2k_encoder_thread.cc index 6975d9221..e6c256f11 100644 --- a/src/lib/grok_j2k_encoder_thread.cc +++ b/src/lib/grok_j2k_encoder_thread.cc @@ -67,6 +67,8 @@ try if (_context->launch(frame, grok.selected) && _context->scheduleCompress(frame)) { frame_guard.cancel(); } + + boost::this_thread::interruption_point(); } } catch (boost::thread_interrupted& e) diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc index b416f921d..3aaaa4e76 100644 --- a/src/lib/j2k_encoder.cc +++ b/src/lib/j2k_encoder.cc @@ -475,13 +475,19 @@ J2KEncoder::retry(DCPVideo video) { #ifdef DCPOMATIC_GROK { - boost::mutex::scoped_lock lock(_threads_mutex); - auto is_grok_thread_with_errors = [](shared_ptr thread) { - auto grok = dynamic_pointer_cast(thread); - return grok && grok->errors(); - }; - - _give_up = std::any_of(_threads.begin(), _threads.end(), is_grok_thread_with_errors); + /* We might be destroying or remaking these threads, and hopefully in that case we'll come back here + * to check again; we definitely don't want to block in that case waiting to be allowed to check + * _threads. + */ + boost::mutex::scoped_lock lock(_threads_mutex, boost::try_to_lock); + if (lock) { + auto is_grok_thread_with_errors = [](shared_ptr thread) { + auto grok = dynamic_pointer_cast(thread); + return grok && grok->errors(); + }; + + _give_up = std::any_of(_threads.begin(), _threads.end(), is_grok_thread_with_errors); + } } #endif diff --git a/test/j2k_encode_threading_test.cc b/test/j2k_encode_threading_test.cc index 48a639faa..58f354e80 100644 --- a/test/j2k_encode_threading_test.cc +++ b/test/j2k_encode_threading_test.cc @@ -25,6 +25,9 @@ #include "lib/dcp_transcode_job.h" #include "lib/encode_server_description.h" #include "lib/film.h" +#ifdef DCPOMATIC_GROK +#include "lib/grok/context.h" +#endif #include "lib/j2k_encoder.h" #include "lib/job_manager.h" #include "lib/make_dcp.h" @@ -115,3 +118,31 @@ BOOST_AUTO_TEST_CASE(frames_not_lost_when_threads_disappear) BOOST_REQUIRE_EQUAL(dcp.cpls()[0]->reels()[0]->main_picture()->intrinsic_duration(), 423U); } + +#ifdef DCPOMATIC_GROK +BOOST_AUTO_TEST_CASE(transcode_stops_when_gpu_enabled_with_no_gpu) +{ + ConfigRestorer cr; + + grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); + + Config::Grok grok; + grok.enable = true; + Config::instance()->set_grok(grok); + + auto content = content_factory(TestPaths::private_data() / "clapperboard.mp4"); + auto film = new_test_film("transcode_stops_when_gpu_enabled_with_no_gpu", content); + film->write_metadata(); + auto job = make_dcp(film, TranscodeJob::ChangedBehaviour::IGNORE); + + int slept = 0; + while (JobManager::instance()->work_to_do() && slept < 10) { + dcpomatic_sleep_seconds(1); + ++slept; + } + + BOOST_REQUIRE(slept < 10); + + JobManager::drop(); +} +#endif -- cgit v1.2.3