return producer;
}
+std::shared_ptr<executor>& producer_destroyer()
+{
+ static auto destroyer = []
+ {
+ auto result = std::make_shared<executor>(L"Producer destroyer");
+ result->set_capacity(std::numeric_limits<unsigned int>::max());
+ return result;
+ }();;
+
+ return destroyer;
+}
+
tbb::atomic<bool>& destroy_producers_in_separate_thread()
{
static tbb::atomic<bool> state;
void destroy_producers_synchronously()
{
destroy_producers_in_separate_thread() = false;
+ // Join destroyer, executing rest of producers in queue synchronously.
+ producer_destroyer().reset();
}
class destroy_producer_proxy : public frame_producer
virtual ~destroy_producer_proxy()
{
- static tbb::atomic<int> counter;
- static std::once_flag counter_init_once;
- std::call_once(counter_init_once, []{ counter = 0; });
-
if(producer_ == core::frame_producer::empty() || !destroy_producers_in_separate_thread())
return;
- ++counter;
- CASPAR_VERIFY(counter < 8);
+ auto destroyer = producer_destroyer();
+
+ if (!destroyer)
+ return;
+
+ CASPAR_VERIFY(destroyer->size() < 8);
auto producer = new spl::shared_ptr<frame_producer>(std::move(producer_));
- boost::thread([=]
+
+ destroyer->begin_invoke([=]
{
std::unique_ptr<spl::shared_ptr<frame_producer>> pointer_guard(producer);
auto str = (*producer)->print();
try
{
- ensure_gpf_handler_installed_for_thread(u8(L"Destroyer: " + str).c_str());
-
if (!producer->unique())
CASPAR_LOG(debug) << str << L" Not destroyed on asynchronous destruction thread: " << producer->use_count();
else
{
CASPAR_LOG_CURRENT_EXCEPTION();
}
-
- --counter;
- }).detach();
+ });
}
draw_frame receive() override {return producer_->receive();}