]> git.sesse.net Git - casparcg/blob - common/concurrency/function_task.h
2.0.0.2:
[casparcg] / common / concurrency / function_task.h
1 #pragma once\r
2 \r
3 #include <tbb/task.h>\r
4 #include <tbb/concurrent_queue.h>\r
5 #include <boost/thread/future.hpp>\r
6 \r
7 namespace caspar { namespace common { namespace function_task {\r
8         \r
9 namespace detail {\r
10         \r
11         template<typename Func>\r
12         class packaged_task : public tbb::task\r
13         {\r
14         public:\r
15                 packaged_task(boost::packaged_task<Func>&& task) : task_(std::forward<boost::packaged_task<Func>>(task)) {}\r
16         \r
17         private:\r
18                 tbb::task* execute() \r
19                 {\r
20                         task_();\r
21                         return nullptr;\r
22                 }\r
23 \r
24                 boost::packaged_task<Func> task_;\r
25         };\r
26 \r
27         template<typename Func>\r
28         class internal_function_task : public tbb::task\r
29         {\r
30         public:\r
31                 internal_function_task(Func&& func) : func_(std::forward<Func>(func)) {}\r
32         private:\r
33                 tbb::task* execute() \r
34                 {\r
35                         func_();\r
36                         return nullptr;\r
37                 }\r
38 \r
39                 Func func_;\r
40         };\r
41 }\r
42                 \r
43 template <typename Func>\r
44 void enqueue(Func&& func)\r
45 {\r
46         tbb::task::enqueue(*new(tbb::task::allocate_root()) detail::internal_function_task<Func>(std::forward<Func>(func)));\r
47 }\r
48 \r
49 template<typename Func>\r
50 auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())>\r
51 {                       \r
52         auto task = boost::packaged_task<decltype(func())>(std::forward<Func>(func));\r
53         auto future = task.get_future();\r
54         tbb::task::enqueue(*new(tbb::task::allocate_root()) detail::packaged_task<decltype(func())>(boost::move(task)));                \r
55         return std::move(future);               \r
56 }\r
57 \r
58 template<typename Func>\r
59 auto invoke(Func&& func) -> decltype(func())\r
60 {       \r
61         return function_task::begin_invoke(std::forward<Func>(func)).get();             \r
62 }\r
63 \r
64 };\r
65 \r
66 }}