CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
async.h
1
3#pragma once
4
5#include <functional>
6#include <system/object_ext.h>
7#include <system/action.h>
8#include <system/threading/tasks/result_task.h>
9#include <system/threading/tasks/task_status.h>
10#include <system/details/dereference.h>
11
12namespace System { namespace Details {
13
17struct ASPOSECPP_SHARED_CLASS AsyncContextBase
18{
20 AsyncContextBase() : stage(0), m_executing(false) {}
22 AsyncContextBase(const AsyncContextBase& other) : AsyncContextBase() {}
23
25 ASPOSECPP_SHARED_API void Continue();
33 template<typename T>
34 bool Await(const T& awaitee, int32_t step)
35 {
36 return AwaitImpl(awaitee, step, [](const auto& awaiter) { awaiter.GetResult(); });
37 }
47 template <typename T, typename V>
48 bool Await(const T& awaitee, V& value, int32_t step)
49 {
50 return AwaitImpl(awaitee, step, [&value](const auto& awaiter) { value = ExplicitCast<V>(awaiter.GetResult()); });
51 }
52
54 ASPOSECPP_SHARED_API void operator()();
55
57 int32_t stage;
58
59protected:
61 using Continuer = std::function<void()>;
62
64 virtual Threading::Tasks::Task* get_Task() const = 0;
66 virtual void Execute() = 0;
75 template <typename AwaiteeT, typename ContinuerT>
76 bool AwaitImpl(const AwaiteeT& awaitee, int32_t stage, const ContinuerT& continuer)
77 {
78 // Getting awaiter instance
79 auto awaiter = Dereference(awaitee).GetAwaiter();
80
81 // Trying to avoid sleeping if awaiter completed already
82 if (awaiter.get_IsCompleted())
83 {
84 continuer(awaiter);
85 return false;
86 }
87
88 // Going to suspend
89 Suspend([awaiter, continuer]() { continuer(awaiter); }, stage);
90
91 // Getting resume context (we need to get it here because resuming should be executed in other context)
92 auto continuationContext = GetResumeScheduler(awaiter.continueOnCapturedContext);
93
94 // Keep task until it should resumed.
95 get_Task()->SharedRefAdded();
96
97 // Setting up resume action
98 awaiter.OnCompleted(Action<>([this, continuationContext]
99 {
100 // Resume task
101 Resume(continuationContext);
102
103 // Release task. It should be kept by someone else (task shcheduler) or destroyed here
104 get_Task()->SharedRefRemovedSafe();
105 }));
106
107 return true;
108 }
110 ASPOSECPP_SHARED_API void Suspend(Continuer&& continuer, int32_t stage);
112 ASPOSECPP_SHARED_API SharedPtr<Threading::Tasks::TaskScheduler> GetResumeScheduler(bool continueOnCapturedContext) const;
114 ASPOSECPP_SHARED_API void Resume(const SharedPtr<Threading::Tasks::TaskScheduler>& context);
115
117 Continuer m_continuer;
119 bool m_executing;
121 SharedPtr<Threading::Tasks::TaskScheduler> m_activator;
123 std::mutex m_state_mutex;
124};
125
128using AsyncFunction = std::function<void(struct AsyncContext&)>;
129
132struct AsyncContext : AsyncContextBase
133{
136 AsyncContext(Threading::Tasks::Task* task, const AsyncFunction& fnc) : m_task(task), m_function(fnc)
137 {}
138
140 ASPOSECPP_SHARED_API void Return();
141
142protected:
144 Threading::Tasks::Task* get_Task() const override {return m_task;}
146 void Execute() override {m_function(*this);}
147
149 Threading::Tasks::Task* m_task;
151 AsyncFunction m_function;
152};
153
154template<typename T>
155struct ResultAsyncContext;
156
161template <typename T>
162using ResultAsyncFunction = std::function<void(ResultAsyncContext<T>&)>;
163
167template<typename T>
168struct ResultAsyncContext : AsyncContextBase
169{
172 ResultAsyncContext(Threading::Tasks::ResultTask<T>* task, const ResultAsyncFunction<T>& fnc) : m_result_task(task), m_function(fnc)
173 {}
174
179 void Return(const T& result)
180 {
181 m_result_task->set_Result(result);
182 m_result_task->set_Status(Threading::Tasks::TaskStatus::RanToCompletion);
183 }
184
185protected:
187 Threading::Tasks::Task* get_Task() const override {return m_result_task;}
189 void Execute() override {m_function(*this);}
190
192 Threading::Tasks::ResultTask<T>* m_result_task;
194 ResultAsyncFunction<T> m_function;
195};
196
197} // namespace Details
198
199ASPOSECPP_SHARED_API TaskPtr MakeAsync(const Details::AsyncFunction& fnc);
200
201template<typename T>
202RTaskPtr<T> MakeAsync(const Details::ResultAsyncFunction<T>& fnc)
203{
204 auto result = System::MakeObject<Threading::Tasks::ResultTask<T>>();
205 result->set_Function(Details::ResultAsyncContext<T>(result.GetPointer(), fnc));
206 result->RunSynchronously();
207 return result;
208}
209
210} // namespace System
void set_Function(const FunctionT &fnc)
Sets the internal function to execute.
Definition: task.h:131
@ Suspend
Suspension of a logical operation.
@ Resume
Resumption of a logical operation.
@ Continue
The 'Continue' status code that equals to HTTP status 100.
Definition: db_command.h:9
TaskPtr MakeAsync(const Details::AsyncFunction &fnc)