abandoned my template based approach of tackling code dupe. closes #1.
I've decided, that the approach was too complex, you can look at the
code in commit f4eead282f
, it's some of
the worst template-magic I have ever written and it didn't even work in
that state. now it is handled simply via a bool parameter, the compiler
should optimize it away anyway
This commit is contained in:
parent
f4eead282f
commit
923680f44b
@ -52,23 +52,9 @@ class thread_pool
|
|||||||
/* the main loop of the threads */
|
/* the main loop of the threads */
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
class place_front_policy
|
template <typename F, typename... Args>
|
||||||
{
|
auto _add_task_internal(bool front, F&& f, Args&&... args)
|
||||||
public:
|
-> std::future<decltype(f(std::forward<Args>(args)...))>;
|
||||||
template <typename F, typename... Args>
|
|
||||||
static void place(std::shared_ptr<std::packaged_task<decltype(std::declval<F>()(std::declval<Args>()...))>> task,
|
|
||||||
std::deque<std::function<void()>>& queue, std::mutex& mu)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mu);
|
|
||||||
queue.emplace_back([task](){ (*task)(); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename F, typename... Args, class placement_policy = place_front_policy>
|
|
||||||
auto _add_task_internal(F&& f, Args&&... args) -> std::future<decltype(f(std::forward<Args>(args)...))>;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -86,7 +72,6 @@ public:
|
|||||||
template <typename R> void priority_task(std::packaged_task<R()>&& ) = delete;
|
template <typename R> void priority_task(std::packaged_task<R()>&& ) = delete;
|
||||||
|
|
||||||
/* adding tasks to the queue */
|
/* adding tasks to the queue */
|
||||||
// TODO: use template-based policies to deal with priority tasks to avoid code-dupe.
|
|
||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
auto add_task(F&& f, Args&&... args) -> std::future<decltype(f(std::forward<Args>(args)...))>;
|
auto add_task(F&& f, Args&&... args) -> std::future<decltype(f(std::forward<Args>(args)...))>;
|
||||||
|
|
||||||
@ -104,17 +89,22 @@ public:
|
|||||||
/* means of getting information */
|
/* means of getting information */
|
||||||
inline size_t get_thread_num() const { return workers.size(); }
|
inline size_t get_thread_num() const { return workers.size(); }
|
||||||
inline size_t get_queue_size() const { return queue.size(); }
|
inline size_t get_queue_size() const { return queue.size(); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename F, typename... Args, class placement_policy>
|
template <typename F, typename... Args>
|
||||||
auto thread_pool::_add_task_internal(F&& f, Args&&... args)
|
auto thread_pool::_add_task_internal(bool front, F&& f, Args&&... args)
|
||||||
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
||||||
{
|
{
|
||||||
auto pckgd_tsk = std::make_shared<std::packaged_task<decltype(f(std::forward<Args>(args)...))()> >
|
auto pckgd_tsk = std::make_shared<std::packaged_task<decltype(f(std::forward<Args>(args)...))()> >
|
||||||
(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
|
(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
|
||||||
|
|
||||||
placement_policy::place(pckgd_tsk, queue, mu);
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mu);
|
||||||
|
if (front)
|
||||||
|
queue.emplace_front([pckgd_tsk](){ (*pckgd_tsk)(); });
|
||||||
|
else
|
||||||
|
queue.emplace_back([pckgd_tsk](){ (*pckgd_tsk)(); });
|
||||||
|
}
|
||||||
cond.notify_one();
|
cond.notify_one();
|
||||||
|
|
||||||
return pckgd_tsk->get_future();
|
return pckgd_tsk->get_future();
|
||||||
@ -140,34 +130,14 @@ template <typename F, typename... Args>
|
|||||||
auto thread_pool::add_task(F&& f, Args&&... args)
|
auto thread_pool::add_task(F&& f, Args&&... args)
|
||||||
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
||||||
{
|
{
|
||||||
auto pckgd_tsk = std::make_shared<std::packaged_task<decltype(f(std::forward<Args>(args)...))()> >
|
return _add_task_internal(false, std::forward<F>(f), std::forward<Args>(args)...);
|
||||||
(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mu);
|
|
||||||
queue.emplace_back([pckgd_tsk](){ (*pckgd_tsk)(); });
|
|
||||||
}
|
|
||||||
cond.notify_one();
|
|
||||||
|
|
||||||
return pckgd_tsk->get_future();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
auto thread_pool::priority_task(F&& f, Args&&... args)
|
auto thread_pool::priority_task(F&& f, Args&&... args)
|
||||||
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
-> std::future<decltype(f(std::forward<Args>(args)...))>
|
||||||
{
|
{
|
||||||
auto pckgd_tsk = std::make_shared<std::packaged_task<decltype(f(std::forward<Args>(args)...))()> >
|
return _add_task_internal(true, std::forward<F>(f), std::forward<Args>(args)...);
|
||||||
(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
|
|
||||||
|
|
||||||
auto ret_val= pckgd_tsk->get_future();
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mu);
|
|
||||||
queue.emplace_front([pckgd_tsk](){ (*pckgd_tsk)(); });
|
|
||||||
}
|
|
||||||
cond.notify_one();
|
|
||||||
|
|
||||||
return ret_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
|
Loading…
Reference in New Issue
Block a user