3 #include "../exception/exceptions.h"
\r
4 #include "../exception/win32_exception.h"
\r
6 #include <boost/thread.hpp>
\r
8 #include <tbb/atomic.h>
\r
9 #include <tbb/concurrent_queue.h>
\r
11 #include <functional>
\r
13 namespace caspar { namespace common {
\r
18 explicit executor(const std::function<void()>& run_func = nullptr)
\r
20 is_running_ = false;
\r
21 run_func_ = run_func != nullptr ? run_func : [=]{run();};
\r
31 if(is_running_.fetch_and_store(true))
\r
33 thread_ = boost::thread(run_func_);
\r
36 bool is_running() const
\r
43 if(is_running_.fetch_and_store(false))
\r
45 execution_queue_.clear();
\r
46 execution_queue_.push([](){});
\r
53 std::function<void()> func;
\r
54 execution_queue_.pop(func);
\r
60 std::function<void()> func;
\r
61 if(execution_queue_.try_pop(func))
\r
64 return func != nullptr;
\r
69 execution_queue_.clear();
\r
72 template<typename Func>
\r
73 void enqueue(Func&& func)
\r
75 execution_queue_.push([=]{try{func();}catch(...){CASPAR_LOG_CURRENT_EXCEPTION();}});
\r
78 template<typename Func>
\r
79 auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())>
\r
81 typedef decltype(func()) result_type;
\r
83 auto task = std::make_shared<boost::packaged_task<result_type>>(std::forward<Func>(func));
\r
84 auto future = task->get_future();
\r
86 if(boost::this_thread::get_id() != thread_.get_id())
\r
87 execution_queue_.push([=]{(*task)();});
\r
91 return std::move(future);
\r
94 template<typename Func>
\r
95 auto invoke(Func&& func) -> decltype(func())
\r
97 return begin_invoke(std::forward<Func>(func)).get();
\r
104 win32_exception::install_handler();
\r
109 std::function<void()> run_func_;
\r
110 boost::thread thread_;
\r
111 tbb::atomic<bool> is_running_;
\r
112 tbb::concurrent_bounded_queue<std::function<void()>> execution_queue_;
\r