X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fproducer%2Fframe_producer.cpp;h=a17fa10ba673003985e0392b23a8eafe211abfbf;hb=a486c25d5e6ce0ebe08e9a2d793a447ff3cb797a;hp=f881d2adbb6d36353912b8cfb8b56b3c12e23335;hpb=8f091990c8e3c1997b4b2d89f97b319cb6ea889d;p=casparcg diff --git a/core/producer/frame_producer.cpp b/core/producer/frame_producer.cpp index f881d2adb..a17fa10ba 100644 --- a/core/producer/frame_producer.cpp +++ b/core/producer/frame_producer.cpp @@ -28,11 +28,55 @@ #include "separated/separated_producer.h" #include +#include #include +#include namespace caspar { namespace core { std::vector g_factories; + +class destroy_producer_proxy : public frame_producer +{ + safe_ptr producer_; + executor& destroy_context_; +public: + destroy_producer_proxy(executor& destroy_context, const safe_ptr& producer) + : producer_(producer) + , destroy_context_(destroy_context){} + + ~destroy_producer_proxy() + { + if(destroy_context_.size() > 4) + CASPAR_LOG(error) << L" Potential destroyer deadlock."; + + // Hacks to bypass compiler bugs. + auto mov_producer = make_move_on_copy>(std::move(producer_)); + auto empty_producer = frame_producer::empty(); + destroy_context_.begin_invoke([=] + { + if(!mov_producer.value.unique()) + CASPAR_LOG(debug) << mov_producer.value->print() << L" Not destroyed on safe asynchronous destruction thread."; + else + CASPAR_LOG(debug) << mov_producer.value->print() << L" Destroying on safe asynchronous destruction thread."; + + mov_producer.value = empty_producer; + }); + } + + virtual safe_ptr receive(int hints) {return producer_->receive(hints);} + virtual safe_ptr last_frame() const {return producer_->last_frame();} + virtual std::wstring print() const {return producer_->print();} + virtual void param(const std::wstring& str) {producer_->param(str);} + virtual safe_ptr get_following_producer() const {return producer_->get_following_producer();} + virtual void set_leading_producer(const safe_ptr& producer) {producer_->set_leading_producer(producer);} + virtual int64_t nb_frames() const {return producer_->nb_frames();} +}; + +safe_ptr create_destroy_producer_proxy(executor& destroy_context, const safe_ptr& producer) +{ + return make_safe(destroy_context, producer); +} class last_frame_producer : public frame_producer {