- \r
-class destroy_producer_proxy : public frame_producer\r
-{ \r
- std::shared_ptr<frame_producer>* producer_;\r
-public:\r
- destroy_producer_proxy(safe_ptr<frame_producer>&& producer) \r
- : producer_(new std::shared_ptr<frame_producer>(std::move(producer)))\r
- {\r
- }\r
-\r
- ~destroy_producer_proxy()\r
- { \r
- static auto destroyers = std::make_shared<tbb::concurrent_bounded_queue<std::shared_ptr<executor>>>();\r
- static tbb::atomic<int> destroyer_count;\r
-\r
- try\r
- {\r
- std::shared_ptr<executor> destroyer;\r
- if(!destroyers->try_pop(destroyer))\r
- {\r
- destroyer.reset(new executor(L"destroyer"));\r
- destroyer->set_priority_class(below_normal_priority_class);\r
- if(++destroyer_count > 16)\r
- CASPAR_LOG(warning) << L"Potential destroyer dead-lock detected.";\r
- CASPAR_LOG(trace) << "Created destroyer: " << destroyer_count;\r
- }\r
- \r
- auto producer = producer_;\r
- auto pool = destroyers;\r
- destroyer->begin_invoke([=]\r
- {\r
- try\r
- {\r
- if(!producer->unique())\r
- CASPAR_LOG(trace) << (*producer)->print() << L" Not destroyed on safe asynchronous destruction thread: " << producer->use_count();\r
- else\r
- CASPAR_LOG(trace) << (*producer)->print() << L" Destroying on safe asynchronous destruction thread.";\r
- }\r
- catch(...){}\r
-\r
- delete producer;\r
- pool->push(destroyer);\r
- }); \r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- try\r
- {\r
- delete producer_;\r
- }\r
- catch(...){}\r
- }\r
- }\r