41using std::unique_lock;
43using std::condition_variable;
85{
return std::thread::hardware_concurrency();}
97 #ifdef HAVE_MULTITHREADING_SUPPORT
110 std::shared_ptr<std::thread> thread;
116 wait_to_execute_a_task(queue::priv*);
128 std::atomic<bool> bring_workers_down;
130 size_t num_workers = 0;
133 mutex tasks_todo_mutex;
138 condition_variable tasks_todo_cond;
141 mutex tasks_done_mutex;
143 std::queue<task_sptr> tasks_staged;
144 mutex tasks_staged_mutex;
146 std::queue<task_sptr> tasks_todo;
148 vector<task_sptr> tasks_done;
154 static task_done_notify default_notify;
158 task_done_notify& notify;
160 vector<std::shared_ptr<worker>>workers;
171 task_done_notify& n = default_notify)
172 : bring_workers_down(false),
173 num_workers(nb_workers),
181 tasks_todo_queue_is_empty()
183 lock_guard<mutex> lock(tasks_todo_mutex);
184 return tasks_todo.empty();
192 for (
unsigned i = 0; i < num_workers; ++i)
194 std::shared_ptr<worker> w(
new worker);
195 w->thread.reset(
new std::thread(&worker::wait_to_execute_a_task,
197 workers.push_back(w);
213 schedule_task(
const task_sptr& t)
215 if (workers.empty() || !t)
219 unique_lock<mutex> lock(tasks_todo_mutex);
220 if (bring_workers_down)
226 tasks_todo_cond.notify_one();
243 for (tasks_type::const_iterator t = tasks.begin(); t != tasks.end(); ++t)
244 is_ok &= schedule_task(*t);
260 stage_task(
const task_sptr& task)
262 unique_lock<mutex> lock(tasks_staged_mutex);
263 tasks_staged.push(task);
270 schedule_staged_tasks()
272 unique_lock<mutex> lock(tasks_staged_mutex);
273 while (!tasks_staged.empty())
275 task_sptr t = tasks_staged.front();
296 do_bring_workers_down()
305 unique_lock<mutex> lock(tasks_todo_mutex);
306 bring_workers_down =
true;
307 tasks_todo_cond.notify_all();
310 for (
auto& worker : workers)
311 worker->thread->join();
318 {do_bring_workers_down();}
323queue::task_done_notify queue::priv::default_notify;
339 : p_(new priv(number_of_workers))
356 : p_(new priv(number_of_workers, notifier))
365{
return p_->tasks_todo.size();}
379{
return p_->schedule_task(t);}
391{
return p_->schedule_tasks(tasks);}
406{
return p_->stage_task(
task);}
412{p_->schedule_staged_tasks();}
425{p_->do_bring_workers_down();}
432{
return p_->tasks_done;}
460worker::wait_to_execute_a_task(queue::priv* p)
466 unique_lock<mutex> lock(p->tasks_todo_mutex);
470 while (p->tasks_todo.empty() && !p->bring_workers_down)
471 p->tasks_todo_cond.wait(lock);
475 if (!p->tasks_todo.empty())
477 t = p->tasks_todo.front();
497 lock_guard<mutex> lock(p->tasks_done_mutex);
498 p->tasks_done.push_back(t);
504 if (p->bring_workers_down && p->tasks_todo_queue_is_empty())