#pragma once\r
\r
#include "../exception/win32_exception.h"\r
-#include "../utility/assert.h"\r
+#include "../utility/string.h"\r
+#include "../utility/move_on_copy.h"\r
#include "../log/log.h"\r
\r
#include <tbb/atomic.h>\r
\r
}\r
\r
-enum priority\r
+enum task_priority\r
{\r
high_priority,\r
normal_priority,\r
priority_count\r
};\r
\r
-namespace internal\r
+enum thread_priority\r
{\r
- template<typename T>\r
- struct move_on_copy\r
- {\r
- move_on_copy(const move_on_copy<T>& other) : value(std::move(other.value)){}\r
- move_on_copy(T&& value) : value(std::move(value)){}\r
- mutable T value;\r
- };\r
-\r
- template<typename T>\r
- move_on_copy<T> make_move_on_copy(T&& value)\r
- {\r
- return move_on_copy<T>(std::move(value));\r
- }\r
-}\r
+ high_priority_class,\r
+ above_normal_priority_class,\r
+ normal_priority_class,\r
+ below_normal_priority_class\r
+};\r
\r
class executor : boost::noncopyable\r
{\r
virtual ~executor() // noexcept\r
{\r
stop();\r
+ execution_queue_[normal_priority].try_push([]{}); // Wake the execution thread.\r
join();\r
}\r
\r
{\r
execution_queue_[normal_priority].set_capacity(capacity);\r
}\r
+\r
+ void set_priority_class(thread_priority p)\r
+ {\r
+ begin_invoke([=]\r
+ {\r
+ if(p == high_priority_class)\r
+ SetThreadPriority(GetCurrentThread(), HIGH_PRIORITY_CLASS);\r
+ if(p == above_normal_priority_class)\r
+ SetThreadPriority(GetCurrentThread(), ABOVE_NORMAL_PRIORITY_CLASS);\r
+ else if(p == normal_priority_class)\r
+ SetThreadPriority(GetCurrentThread(), NORMAL_PRIORITY_CLASS);\r
+ else if(p == below_normal_priority_class)\r
+ SetThreadPriority(GetCurrentThread(), BELOW_NORMAL_PRIORITY_CLASS);\r
+ });\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
\r
template<typename Func>\r
- auto begin_invoke(Func&& func, priority priority = normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
+ auto 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 = internal::make_move_on_copy(create_task(func));\r
+ auto task_adaptor = make_move_on_copy(create_task(func));\r
\r
auto future = task_adaptor.value.get_future();\r
\r
}\r
\r
template<typename Func>\r
- auto try_begin_invoke(Func&& func, priority priority = normal_priority) -> boost::unique_future<decltype(func())> // noexcept\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 = internal::make_move_on_copy(create_task(func));\r
+ auto task_adaptor = make_move_on_copy(create_task(func));\r
\r
auto future = task_adaptor.value.get_future();\r
\r
}\r
\r
template<typename Func>\r
- auto invoke(Func&& func, priority prioriy = normal_priority) -> decltype(func()) // noexcept\r
+ auto 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
\r
template<typename Func>\r
- auto try_invoke(Func&& func, priority prioriy = normal_priority) -> decltype(func()) // noexcept\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
win32_exception::install_handler(); \r
detail::SetThreadName(GetCurrentThreadId(), name_.c_str());\r
while(is_running_)\r
- execute();\r
+ {\r
+ try\r
+ {\r
+ execute();\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ }\r
+ }\r
} \r
};\r
\r