From: Helge Norberg Date: Wed, 4 Sep 2013 13:36:43 +0000 (+0200) Subject: Fixed bug where av_lockmgr unregistration occurred before avcodec_close at server... X-Git-Tag: 2.0.6~50 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=461c2023b3052bdd1cf35a64dc83fdd20b40fb3d;hp=112151c2b10d697e98e567041bed0920946a1edc;p=casparcg Fixed bug where av_lockmgr unregistration occurred before avcodec_close at server exit --- diff --git a/core/producer/frame_producer.cpp b/core/producer/frame_producer.cpp index 066f7fce6..b2dce74ec 100644 --- a/core/producer/frame_producer.cpp +++ b/core/producer/frame_producer.cpp @@ -39,6 +39,18 @@ namespace caspar { namespace core { std::vector g_factories; std::vector g_thumbnail_factories; + +tbb::atomic& destroy_producers_in_separate_thread() +{ + static tbb::atomic state; + + return state; +} + +void destroy_producers_synchronously() +{ + destroy_producers_in_separate_thread() = false; +} class destroy_producer_proxy : public frame_producer { @@ -47,13 +59,34 @@ public: destroy_producer_proxy(safe_ptr&& producer) : producer_(new std::shared_ptr(std::move(producer))) { + destroy_producers_in_separate_thread() = true; } ~destroy_producer_proxy() - { + { static auto destroyers = std::make_shared>>(); static tbb::atomic destroyer_count; + if (!destroy_producers_in_separate_thread()) + { + try + { + producer_.reset(); + + std::shared_ptr destroyer; + + // Destruct any executors, causing them to execute pending tasks + while (destroyers->try_pop(destroyer)) + --destroyer_count; + } + catch (...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } + + return; + } + try { std::shared_ptr destroyer; diff --git a/core/producer/frame_producer.h b/core/producer/frame_producer.h index 678ddbd2a..1e07ecde6 100644 --- a/core/producer/frame_producer.h +++ b/core/producer/frame_producer.h @@ -92,5 +92,6 @@ safe_ptr create_producer(const safe_ptr&, c safe_ptr create_producer_destroy_proxy(safe_ptr producer); safe_ptr create_producer_print_proxy(safe_ptr producer); safe_ptr create_thumbnail_producer(const safe_ptr& factory, const std::wstring& media_file); +void destroy_producers_synchronously(); }} diff --git a/shell/server.cpp b/shell/server.cpp index b93351790..a1233df13 100644 --- a/shell/server.cpp +++ b/shell/server.cpp @@ -129,12 +129,13 @@ struct server::implementation : boost::noncopyable ~implementation() { - ffmpeg::uninit(); - thumbnail_generator_.reset(); primary_amcp_server_.reset(); async_servers_.clear(); + destroy_producers_synchronously(); channels_.clear(); + + ffmpeg::uninit(); } void setup_audio(const boost::property_tree::wptree& pt)