#include <tbb/concurrent_queue.h>\r
\r
#include <boost/thread.hpp>\r
+#include <boost/optional.hpp>\r
#include <boost/noncopyable.hpp>\r
\r
#include <functional>\r
virtual ~executor() // noexcept\r
{\r
stop();\r
- execution_queue_[normal_priority].try_push([]{}); // Wake the execution thread.\r
join();\r
}\r
\r
void stop() // noexcept\r
{\r
is_running_ = false; \r
+ execution_queue_[normal_priority].try_push([]{}); // Wake the execution thread.\r
}\r
\r
void wait() // noexcept\r
\r
return std::move(future); \r
}\r
-\r
- template<typename Func>\r
- auto try_begin_invoke(Func&& func, task_priority priority = normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
- {\r
- // Create a move on copy adaptor to avoid copying the functor into the queue, tbb::concurrent_queue does not support move semantics.\r
- auto task_adaptor = make_move_on_copy(create_task(func));\r
- \r
- auto future = task_adaptor.value.get_future();\r
-\r
- if(priority == normal_priority || execution_queue_[normal_priority].try_push(nullptr))\r
- { \r
- execution_queue_[priority].try_push([=]\r
- {\r
- try{task_adaptor.value();}\r
- catch(boost::task_already_started&){}\r
- catch(...){CASPAR_LOG_CURRENT_EXCEPTION();}\r
- });\r
- }\r
- \r
- return std::move(future); \r
- }\r
-\r
+ \r
template<typename Func>\r
auto invoke(Func&& func, task_priority prioriy = normal_priority) -> decltype(func()) // noexcept\r
{\r
\r
return begin_invoke(std::forward<Func>(func), prioriy).get();\r
}\r
-\r
- template<typename Func>\r
- auto try_invoke(Func&& func, task_priority prioriy = normal_priority) -> decltype(func()) // noexcept\r
- {\r
- if(boost::this_thread::get_id() == thread_.get_id()) // Avoids potential deadlock.\r
- return func();\r
- \r
- return try_begin_invoke(std::forward<Func>(func), prioriy).get();\r
- }\r
-\r
+ \r
void yield() // noexcept\r
{\r
if(boost::this_thread::get_id() != thread_.get_id()) // Only yield when calling from execution thread.\r