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

View File

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