@@ -19,196 +19,6 @@ using Clock = std::chrono::steady_clock;
1919
2020// -----------------------------------------------------------------------------
2121
22- // We have two types of coroutines:
23- // * Outter or Internal (in TPC-C this is a terminal task). It can sleep (co_awaiting) or wait for another "inner" task.
24- // * Inner or External (in TPC-C this is a transaction task). E.g. it might perform async requests to YDB.
25- // when it is finished, terminal task continues. It is called external, because usually it has to use
26- // thread-safe interface of ITaskQueue (future used to co_await is normally set by another thread).
27-
28- template <typename T>
29- struct TTask {
30- struct TPromiseType ;
31- using TCoroHandle = std::coroutine_handle<TPromiseType>;
32-
33- struct TPromiseType {
34- TTask get_return_object () {
35- return TTask{std::coroutine_handle<TPromiseType>::from_promise (*this )};
36- }
37-
38- std::suspend_always initial_suspend () { return {}; }
39-
40- auto final_suspend () noexcept {
41- struct TFinalAwaiter {
42- bool await_ready () noexcept { return false ; }
43- std::coroutine_handle<> await_suspend (TCoroHandle h) noexcept {
44- if (h.promise ().Continuation ) {
45- return h.promise ().Continuation ;
46- }
47- return std::noop_coroutine ();
48- }
49- void await_resume () noexcept {}
50- };
51- return TFinalAwaiter{};
52- }
53-
54- template <typename U>
55- void return_value (U&& v) {
56- Value = std::forward<U>(v);
57- }
58-
59- void unhandled_exception () {
60- Exception = std::current_exception ();
61- }
62-
63- T Value;
64- std::exception_ptr Exception;
65- std::coroutine_handle<> Continuation;
66- };
67-
68- using promise_type = TPromiseType;
69-
70- TTask (TCoroHandle h)
71- : Handle(h)
72- {
73- }
74-
75- // note, default move constructors doesn't null Handle,
76- // so that we need to add our own
77- TTask (TTask&& other) noexcept
78- : Handle(std::exchange(other.Handle, nullptr ))
79- {}
80-
81- TTask& operator =(TTask&& other) noexcept {
82- if (this != &other) {
83- if (Handle) {
84- Handle.destroy ();
85- }
86- Handle = std::exchange (other.Handle , nullptr );
87- }
88- return *this ;
89- }
90-
91- TTask (const TTask&) = delete ;
92- TTask& operator =(const TTask&) = delete ;
93-
94- ~TTask () {
95- if (Handle) {
96- Handle.destroy ();
97- }
98- }
99-
100- // awaitable task
101-
102- bool await_ready () const noexcept {
103- return Handle.done ();
104- }
105-
106- void await_suspend (std::coroutine_handle<> awaiting) {
107- Handle.promise ().Continuation = awaiting;
108- Handle.resume (); // start inner task
109- }
110-
111- T&& await_resume() {
112- if (Handle.promise ().Exception ) {
113- std::rethrow_exception (Handle.promise ().Exception );
114- }
115-
116- return std::move (Handle.promise ().Value );
117- }
118-
119- TCoroHandle Handle;
120- };
121-
122- template <>
123- struct TTask <void > {
124- struct TPromiseType ;
125- using TCoroHandle = std::coroutine_handle<TPromiseType>;
126-
127- struct TPromiseType {
128- TTask get_return_object () {
129- return TTask{std::coroutine_handle<TPromiseType>::from_promise (*this )};
130- }
131-
132- std::suspend_always initial_suspend () { return {}; }
133-
134- auto final_suspend () noexcept {
135- struct TFinalAwaiter {
136- bool await_ready () noexcept { return false ; }
137- std::coroutine_handle<> await_suspend (TCoroHandle h) noexcept {
138- if (h.promise ().Continuation ) {
139- return h.promise ().Continuation ;
140- }
141- return std::noop_coroutine ();
142- }
143- void await_resume () noexcept {}
144- };
145- return TFinalAwaiter{};
146- }
147-
148- void return_void () {}
149-
150- void unhandled_exception () {
151- Exception = std::current_exception ();
152- }
153-
154- std::exception_ptr Exception;
155- std::coroutine_handle<> Continuation;
156- };
157-
158- using promise_type = TPromiseType;
159-
160- TTask (TCoroHandle h)
161- : Handle(h)
162- {
163- }
164-
165- // note, default move constructors doesn't null Handle,
166- // so that we need to add our own
167- TTask (TTask&& other) noexcept
168- : Handle(std::exchange(other.Handle, nullptr ))
169- {}
170-
171- TTask& operator =(TTask&& other) noexcept {
172- if (this != &other) {
173- if (Handle) {
174- Handle.destroy ();
175- }
176- Handle = std::exchange (other.Handle , nullptr );
177- }
178- return *this ;
179- }
180-
181- TTask (const TTask&) = delete ;
182- TTask& operator =(const TTask&) = delete ;
183-
184- ~TTask () {
185- if (Handle) {
186- Handle.destroy ();
187- }
188- }
189-
190- // awaitable task
191-
192- bool await_ready () const noexcept {
193- return Handle.done ();
194- }
195-
196- void await_suspend (std::coroutine_handle<> awaiting) {
197- Handle.promise ().Continuation = awaiting;
198- Handle.resume (); // start inner task
199- }
200-
201- void await_resume () {
202- if (Handle.promise ().Exception ) {
203- std::rethrow_exception (Handle.promise ().Exception );
204- }
205- }
206-
207- TCoroHandle Handle;
208- };
209-
210- // -----------------------------------------------------------------------------
211-
21222class ITaskQueue {
21323public:
21424 struct TThreadStats {
0 commit comments