| 58 | // add new work item to the pool |
| 59 | template<class F, class... Args> |
| 60 | decltype(auto) ThreadPool::enqueue(F&& f, Args&&... args) |
| 61 | { |
| 62 | using return_type = std::invoke_result_t<F, Args...>; |
| 63 | |
| 64 | std::packaged_task<return_type()> task( |
| 65 | std::bind(std::forward<F>(f), std::forward<Args>(args)...) |
| 66 | ); |
| 67 | |
| 68 | std::future<return_type> res = task.get_future(); |
| 69 | { |
| 70 | std::unique_lock<std::mutex> lock(queue_mutex); |
| 71 | |
| 72 | // don't allow enqueueing after stopping the pool |
| 73 | if (stop) |
| 74 | throw std::runtime_error("enqueue on stopped ThreadPool"); |
| 75 | |
| 76 | tasks.emplace(std::move(task)); |
| 77 | } |
| 78 | condition.notify_one(); |
| 79 | return res; |
| 80 | } |