@@ -110,143 +110,84 @@ auto defer_to_blocking(TaskExecutor& exec)
110110// / \param resume_exec task executor where coroutine will resume once the task is run.
111111// / \param callable task to run.
112112// / \return awaitable.
113- template <typename DispatchTaskExecutor,
114- typename ResumeTaskExecutor,
115- typename Callable,
116- typename ResultType = detail::function_return_t <decltype (&std::decay_t <Callable>::operator ())>,
117- std::enable_if_t <not std::is_same<ResultType, void >::value, int > = 0 >
118- auto offload_to_executor (DispatchTaskExecutor& dispatch_exec, ResumeTaskExecutor& resume_exec, Callable&& callable)
113+ template <typename DispatchTaskExecutor, typename ResumeTaskExecutor, typename Callable>
114+ auto try_offload_to_executor (DispatchTaskExecutor& dispatch_exec, ResumeTaskExecutor& resume_exec, Callable&& callable)
119115{
120- struct task_executor_offloader {
121- task_executor_offloader (DispatchTaskExecutor& dispatch_exec_,
122- ResumeTaskExecutor& resume_exec_,
123- Callable callable_) :
124- dispatch_exec (dispatch_exec_), resume_exec(resume_exec_), task(std::forward<Callable>(callable_))
125- {
126- }
127-
128- bool await_ready () noexcept { return false ; }
129-
130- void await_suspend (coro_handle<> suspending_coro)
131- {
132- continuation = suspending_coro;
133- bool dispatched1 = dispatch_exec.execute ([this ]() mutable {
134- result = task ();
135- bool dispatched2 = resume_exec.execute ([this ]() { continuation.resume (); });
136- srsran_assert (dispatched2, " Failed to dispatch task" );
137- });
138- srsran_assert (dispatched1, " Failed to dispatch task" );
139- }
140-
141- ResultType await_resume () { return result; }
142-
143- task_executor_offloader& get_awaiter () { return *this ; }
144-
145- private:
146- DispatchTaskExecutor& dispatch_exec;
147- ResumeTaskExecutor& resume_exec;
148- Callable task;
149- ResultType result;
150- coro_handle<> continuation;
151- };
152- return task_executor_offloader{dispatch_exec, resume_exec, std::forward<Callable>(callable)};
153- }
154-
155- template <typename DispatchTaskExecutor,
156- typename ResumeTaskExecutor,
157- typename Callable,
158- typename ResultType = detail::function_return_t <decltype (&std::decay_t <Callable>::operator ())>,
159- std::enable_if_t <std::is_same<ResultType, void >::value, int > = 0 >
160- auto offload_to_executor (DispatchTaskExecutor& dispatch_exec, ResumeTaskExecutor& resume_exec, Callable&& callable)
161- {
162- struct task_executor_offloader {
163- task_executor_offloader (DispatchTaskExecutor& dispatch_exec_,
164- ResumeTaskExecutor& resume_exec_,
165- Callable callable_) :
166- dispatch_exec (dispatch_exec_), resume_exec(resume_exec_), task(std::forward<Callable>(callable_))
167- {
168- }
169-
170- bool await_ready () noexcept { return false ; }
171-
172- void await_suspend (coro_handle<> suspending_coro)
173- {
174- continuation = suspending_coro;
175- dispatch_exec.execute ([this ]() mutable {
176- task ();
177- resume_exec.execute ([this ]() { continuation.resume (); });
178- });
179- }
180-
181- void await_resume () {}
182-
183- task_executor_offloader& get_awaiter () { return *this ; }
184-
185- private:
186- DispatchTaskExecutor& dispatch_exec;
187- ResumeTaskExecutor& resume_exec;
188- Callable task;
189- coro_handle<> continuation;
190- };
191-
192- return task_executor_offloader{dispatch_exec, resume_exec, std::forward<Callable>(callable)};
193- }
194-
195- // / \brief Returns an async_task<void> that runs a given invocable task in a \c dispatch_exec executor, and once the
196- // / task is complete, it resumes the suspended coroutine in a \c return_exec executor.
197- template <typename DispatchTaskExecutor,
198- typename CurrentTaskExecutor,
199- typename Callable,
200- typename ReturnType = detail::function_return_t <decltype (&Callable::operator ())>>
201- std::enable_if_t<std::is_same<ReturnType, void>::value, async_task<void>>
202- execute_and_continue_on_blocking(DispatchTaskExecutor& dispatch_exec,
203- CurrentTaskExecutor& return_exec,
204- Callable&& callable)
205- {
206- return launch_async ([&return_exec, &dispatch_exec, task = std::forward<Callable>(callable)](
207- coro_context<async_task<void >>& ctx) mutable {
208- CORO_BEGIN (ctx);
209-
210- // Dispatch execution context switch.
211- CORO_AWAIT (execute_on_blocking (dispatch_exec));
212-
213- // Run task.
214- task ();
215-
216- // Continuation in the original executor.
217- CORO_AWAIT (execute_on_blocking (return_exec));
218-
219- CORO_RETURN ();
220- });
221- }
222-
223- // / \brief Returns an async_task<ReturnType> that runs a given invocable task in a \c dispatch_exec executor, and once
224- // / the task is complete, it resumes the suspended coroutine in a \c return_exec executor.
225- template <typename DispatchTaskExecutor,
226- typename CurrentTaskExecutor,
227- typename Callable,
228- typename ReturnType = detail::function_return_t <decltype (&Callable::operator ())>>
229- std::enable_if_t<not std::is_same<ReturnType, void>::value, async_task<ReturnType>>
230- execute_and_continue_on_blocking(DispatchTaskExecutor& dispatch_exec,
231- CurrentTaskExecutor& return_exec,
232- Callable&& callable)
233- {
234- ReturnType ret{};
235- return launch_async ([&return_exec, &dispatch_exec, task = std::forward<Callable>(callable), ret](
236- coro_context<async_task<ReturnType>>& ctx) mutable {
237- CORO_BEGIN (ctx);
238-
239- // Dispatch execution context switch.
240- CORO_AWAIT (execute_on_blocking (dispatch_exec));
241-
242- // Run task.
243- ret = task ();
116+ using result_type = detail::function_return_t <decltype (&std::decay_t <Callable>::operator ())>;
117+
118+ if constexpr (std::is_same_v<result_type, void >) {
119+ // void return case.
120+
121+ struct task_executor_offloader {
122+ task_executor_offloader (DispatchTaskExecutor& dispatch_exec_,
123+ ResumeTaskExecutor& resume_exec_,
124+ Callable callable_) :
125+ dispatch_exec (dispatch_exec_), resume_exec(resume_exec_), task(std::forward<Callable>(callable_))
126+ {
127+ }
128+
129+ bool await_ready () noexcept { return false ; }
130+
131+ void await_suspend (coro_handle<> suspending_coro)
132+ {
133+ continuation = suspending_coro;
134+ dispatch_exec.execute ([this ]() mutable {
135+ task ();
136+ resume_exec.execute ([this ]() { continuation.resume (); });
137+ });
138+ }
139+
140+ void await_resume () {}
141+
142+ task_executor_offloader& get_awaiter () { return *this ; }
143+
144+ private:
145+ DispatchTaskExecutor& dispatch_exec;
146+ ResumeTaskExecutor& resume_exec;
147+ Callable task;
148+ coro_handle<> continuation;
149+ };
244150
245- // Continuation in the original executor.
246- CORO_AWAIT (execute_on_blocking (return_exec));
151+ return task_executor_offloader{dispatch_exec, resume_exec, std::forward<Callable>(callable)};
152+
153+ } else {
154+ // non-void return case.
155+
156+ struct task_executor_offloader {
157+ task_executor_offloader (DispatchTaskExecutor& dispatch_exec_,
158+ ResumeTaskExecutor& resume_exec_,
159+ Callable callable_) :
160+ dispatch_exec (dispatch_exec_), resume_exec(resume_exec_), task(std::forward<Callable>(callable_))
161+ {
162+ }
163+
164+ bool await_ready () noexcept { return false ; }
165+
166+ void await_suspend (coro_handle<> suspending_coro)
167+ {
168+ continuation = suspending_coro;
169+ bool dispatched1 = dispatch_exec.execute ([this ]() mutable {
170+ result = task ();
171+ bool dispatched2 = resume_exec.execute ([this ]() { continuation.resume (); });
172+ srsran_assert (dispatched2, " Failed to dispatch task" );
173+ });
174+ srsran_assert (dispatched1, " Failed to dispatch task" );
175+ }
176+
177+ result_type await_resume () { return result; }
178+
179+ task_executor_offloader& get_awaiter () { return *this ; }
180+
181+ private:
182+ DispatchTaskExecutor& dispatch_exec;
183+ ResumeTaskExecutor& resume_exec;
184+ Callable task;
185+ result_type result;
186+ coro_handle<> continuation;
187+ };
247188
248- CORO_RETURN (ret) ;
249- });
189+ return task_executor_offloader{dispatch_exec, resume_exec, std::forward<Callable>(callable)} ;
190+ }
250191}
251192
252193} // namespace srsran
0 commit comments