allow the use of move_tasks in procedures

This commit is contained in:
Francisco Paisana 2020-04-08 14:00:40 +01:00 committed by Francisco Paisana
parent 309c10b0c6
commit 7932a6bed7
2 changed files with 16 additions and 13 deletions

View File

@ -250,25 +250,26 @@ private:
* Specialization for tasks with content that is move-only
**********************************************************/
class move_task_t
template <typename... Args>
class move_function
{
public:
move_task_t() = default;
move_function() = default;
template <typename Func>
move_task_t(Func&& f) : task_ptr(new derived_task<Func>(std::forward<Func>(f)))
move_function(Func&& f) : task_ptr(new derived_task<Func>(std::forward<Func>(f)))
{
}
void operator()() { (*task_ptr)(); }
void operator()(Args&&... args) { (*task_ptr)(std::forward<Args>(args)...); }
private:
struct base_task {
virtual ~base_task() {}
virtual void operator()() = 0;
virtual void operator()(Args&&...) = 0;
};
template <typename Func>
struct derived_task : public base_task {
derived_task(Func&& f_) : f(std::forward<Func>(f_)) {}
void operator()() final { f(); }
void operator()(Args&&... args) final { f(std::forward<Args>(args)...); }
private:
Func f;
@ -277,6 +278,7 @@ private:
std::unique_ptr<base_task> task_ptr;
};
using move_task_t = move_function<>;
using task_multiqueue = multiqueue_handler<move_task_t>;
} // namespace srslte

View File

@ -19,6 +19,7 @@
*
*/
#include "srslte/common/multiqueue.h"
#include <functional>
#include <list>
#include <memory>
@ -73,7 +74,7 @@ class callback_group_t
{
public:
using callback_id_t = uint32_t;
using callback_t = std::function<void(Args...)>;
using callback_t = srslte::move_function<Args...>;
//! register callback, that gets called once
callback_id_t on_next_call(callback_t f_)
@ -93,11 +94,11 @@ public:
// call all callbacks
template <typename... ArgsRef>
void operator()(const ArgsRef&... args)
void operator()(ArgsRef&&... args)
{
for (auto& f : func_list) {
if (f.active) {
f.func(args...);
f.func(std::forward<ArgsRef>(args)...);
if (not f.call_always) {
f.active = false;
}
@ -274,7 +275,7 @@ public:
using result_type = ResultType;
using proc_result_type = proc_result_t<result_type>;
using proc_future_type = proc_future_t<result_type>;
using then_callback_list_t = callback_group_t<proc_result_type>;
using then_callback_list_t = callback_group_t<const proc_result_type&>;
using callback_t = typename then_callback_list_t::callback_t;
using callback_id_t = typename then_callback_list_t::callback_id_t;
@ -312,8 +313,8 @@ public:
}
//! methods to schedule continuation tasks
callback_id_t then(const callback_t& c) { return complete_callbacks.on_next_call(c); }
callback_id_t then_always(const callback_t& c) { return complete_callbacks.on_every_call(c); }
callback_id_t then(callback_t c) { return complete_callbacks.on_next_call(std::move(c)); }
callback_id_t then_always(callback_t c) { return complete_callbacks.on_every_call(std::move(c)); }
//! launch a procedure, returning true if successful or running and false if it error or it failed to launch
template <class... Args>
@ -363,7 +364,7 @@ protected:
// call T::then() if it exists
proc_detail::optional_then(proc_ptr.get(), &result);
// signal continuations
complete_callbacks(result);
complete_callbacks(std::move(result));
// back to inactive
proc_detail::optional_clear(proc_ptr.get());
proc_state = proc_status_t::idle;