};\r
typedef enum_class<task_priority_def> task_priority;\r
\r
-class executor\r
+class executor sealed\r
{ \r
struct priority_function\r
{\r
\r
const std::wstring name_;\r
tbb::atomic<bool> is_running_;\r
+ boost::thread thread_; \r
function_queue_t execution_queue_;\r
tbb::concurrent_bounded_queue<int> semaphore_;\r
- boost::thread thread_; \r
\r
public: \r
executor(const std::wstring& name)\r
thread_ = boost::thread([this]{run();});\r
}\r
\r
- virtual ~executor()\r
+ ~executor()\r
{\r
try\r
{\r
- internal_begin_invoke([this]\r
+ internal_begin_invoke([=]\r
{\r
is_running_ = false;\r
}).wait();\r
catch(...)\r
{\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
+\r
+ clear();\r
is_running_ = false;\r
+ semaphore_.try_push(0);\r
}\r
thread_.join();\r
}\r
- \r
+ \r
template<typename Func>\r
auto begin_invoke(Func&& func, task_priority priority = task_priority::normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
{ \r
- if(execution_queue_.size() > 256)\r
+ if(execution_queue_.size() > 128)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("executor overflow.") << source_info(name_));\r
- \r
+\r
if(!is_running_)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("executor not running.") << source_info(name_));\r
-\r
- return internal_begin_invoke(std::forward<Func>(func), priority);\r
+ \r
+ return internal_begin_invoke(std::forward<Func>(func), priority); \r
}\r
-\r
+ \r
template<typename Func>\r
auto invoke(Func&& func, task_priority prioriy = task_priority::normal_priority) -> decltype(func()) // noexcept\r
{\r
}\r
\r
private: \r
- \r
+\r
template<typename Func>\r
auto internal_begin_invoke(Func&& func, task_priority priority = task_priority::normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
{ \r