Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | #include "gate/runnables.hpp" | ||
30 | |||
31 | namespace gate | ||
32 | { | ||
33 | |||
34 | |||
35 | |||
36 | 10 | IRunnableBuilder::~IRunnableBuilder() noexcept | |
37 | { | ||
38 | 10 | } | |
39 | |||
40 | 5 | result_t IRunnableBuilder::runnable_run(void* this_ptr) | |
41 | { | ||
42 | 5 | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
43 | 5 | IRunnableBuilder* obj = getInterface<IRunnableBuilder>(dispatcher); | |
44 | try | ||
45 | { | ||
46 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | obj->run(); |
47 | 5 | return results::Ok; | |
48 | } | ||
49 | ✗ | catch (Throwable const& xcpt) | |
50 | { | ||
51 | ✗ | return xcpt.getResult(); | |
52 | } | ||
53 | ✗ | catch (...) | |
54 | { | ||
55 | ✗ | return results::UnknownError; | |
56 | } | ||
57 | } | ||
58 | |||
59 | 2 | IRunnableBuilder::VtblRunnable::VtblRunnable() | |
60 | { | ||
61 | 2 | obj_vtbl_t* this_ptr = reinterpret_cast<obj_vtbl_t*>(this); | |
62 | 2 | this_ptr->run = &IRunnableBuilder::runnable_run; | |
63 | 2 | } | |
64 | |||
65 | IRunnableBuilder::VtblRunnable IRunnableBuilder::cpp_vtbl_runnable; | ||
66 | |||
67 | ✗ | IRunnableBuilder::IRunnableBuilder(obj_vtbl_t const* vtbl_ptr, char const* name) | |
68 | ✗ | : object_builder_t(vtbl_ptr, name) | |
69 | { | ||
70 | ✗ | } | |
71 | |||
72 | 5 | IRunnableBuilder::IRunnableBuilder() | |
73 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | : object_builder_t(&cpp_vtbl_runnable, GATE_INTERFACE_NAME_RUNNABLE) |
74 | { | ||
75 | 5 | } | |
76 | |||
77 | |||
78 | |||
79 | 16 | Runnable::~Runnable() noexcept | |
80 | { | ||
81 | 16 | } | |
82 | 1 | void Runnable::run() | |
83 | { | ||
84 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (this->empty()) |
85 | { | ||
86 | ✗ | GATEXX_RAISE_ERROR(results::NullPointer); | |
87 | } | ||
88 | 1 | gate_result_t result = gate_runnable_run(this->c_impl()); | |
89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATEXX_CHECK_EXCEPTION(result); |
90 | 1 | } | |
91 | |||
92 | 5 | Runnable::Runnable(gate_runnable_t* ptr_runnable) | |
93 | 5 | : object_impl_t(ptr_runnable) | |
94 | { | ||
95 | 5 | } | |
96 | |||
97 | 3 | Runnable::Runnable(Runnable const& src) | |
98 | 3 | : object_impl_t(src) | |
99 | { | ||
100 | 3 | } | |
101 | |||
102 | ✗ | Runnable& Runnable::operator=(Runnable const& src) | |
103 | { | ||
104 | ✗ | object_impl_t::operator=(src); | |
105 | ✗ | return *this; | |
106 | } | ||
107 | |||
108 | |||
109 | |||
110 | 2 | Task::~Task() noexcept | |
111 | { | ||
112 | 2 | } | |
113 | 1 | void Task::run() | |
114 | { | ||
115 | 1 | result_t result = gate_task_run(this->c_impl()); | |
116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATEXX_CHECK_EXCEPTION(result); |
117 | 1 | } | |
118 | |||
119 | ✗ | void Task::cancel() | |
120 | { | ||
121 | ✗ | result_t result = gate_task_cancel(this->c_impl()); | |
122 | ✗ | GATEXX_CHECK_EXCEPTION(result); | |
123 | ✗ | } | |
124 | |||
125 | 1 | Task::Task(gate_task_t* ptr_task) | |
126 | 1 | : object_impl_t(ptr_task) | |
127 | { | ||
128 | 1 | } | |
129 | ✗ | Task::Task(Task const& src) | |
130 | ✗ | : object_impl_t(src) | |
131 | { | ||
132 | |||
133 | ✗ | } | |
134 | ✗ | Task& Task::operator=(Task const& src) | |
135 | { | ||
136 | ✗ | object_impl_t::operator=(src); | |
137 | ✗ | return *this; | |
138 | } | ||
139 | |||
140 | ✗ | Task::StatusEnum Task::status() | |
141 | { | ||
142 | ✗ | return static_cast<Task::StatusEnum>(gate_task_get_status(this->c_impl())); | |
143 | } | ||
144 | |||
145 | ✗ | bool_t Task::completed() | |
146 | { | ||
147 | ✗ | return gate_task_completed(this->c_impl()); | |
148 | } | ||
149 | |||
150 | 1 | void const* Task::getResult() | |
151 | { | ||
152 | 1 | void const* ptrTaskData = NULL; | |
153 | 1 | result_t taskResult = results::Failed; | |
154 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | result_t result = gate_task_get_result(this->c_impl(), &taskResult, &ptrTaskData); |
155 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1 | GATEXX_CHECK_EXCEPTION(result); |
156 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1 | GATEXX_CHECK_EXCEPTION(taskResult); |
157 | 1 | return ptrTaskData; | |
158 | } | ||
159 | |||
160 | ✗ | void Task::wait() | |
161 | { | ||
162 | ✗ | result_t result = gate_task_wait(this->c_impl()); | |
163 | ✗ | GATEXX_CHECK_EXCEPTION(result); | |
164 | ✗ | } | |
165 | |||
166 | ✗ | bool Task::waitFor(uint32_t timeoutMs) | |
167 | { | ||
168 | ✗ | result_t result = gate_task_timed_wait(this->c_impl(), timeoutMs); | |
169 | ✗ | if (GATE_FAILED(result)) | |
170 | { | ||
171 | ✗ | if (result == GATE_RESULT_TIMEOUT) | |
172 | { | ||
173 | ✗ | return false; | |
174 | } | ||
175 | else | ||
176 | { | ||
177 | ✗ | GATEXX_RAISE_EXCEPTION(result, NULL, 0); | |
178 | } | ||
179 | } | ||
180 | ✗ | return true; | |
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | |||
186 | 2 | ITaskBuilder::~ITaskBuilder() noexcept | |
187 | { | ||
188 | |||
189 | 2 | } | |
190 | |||
191 | 1 | result_t ITaskBuilder::task_run(void* this_ptr) | |
192 | { | ||
193 | 1 | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
194 | 1 | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
195 | try | ||
196 | { | ||
197 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | obj->run(); |
198 | 1 | return results::Ok; | |
199 | } | ||
200 | ✗ | catch (Throwable const& xcpt) | |
201 | { | ||
202 | ✗ | return xcpt.getResult(); | |
203 | } | ||
204 | ✗ | catch (...) | |
205 | { | ||
206 | ✗ | return results::UnknownError; | |
207 | } | ||
208 | } | ||
209 | ✗ | result_t ITaskBuilder::task_cancel(void* this_ptr) | |
210 | { | ||
211 | ✗ | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
212 | ✗ | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
213 | try | ||
214 | { | ||
215 | ✗ | obj->cancel(); | |
216 | ✗ | return results::Ok; | |
217 | } | ||
218 | ✗ | catch (Throwable const& xcpt) | |
219 | { | ||
220 | ✗ | return xcpt.getResult(); | |
221 | } | ||
222 | ✗ | catch (...) | |
223 | { | ||
224 | ✗ | return results::UnknownError; | |
225 | } | ||
226 | } | ||
227 | ✗ | int ITaskBuilder::task_get_status(void* this_ptr) | |
228 | { | ||
229 | ✗ | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
230 | ✗ | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
231 | ✗ | return static_cast<int>(obj->status()); | |
232 | } | ||
233 | ✗ | gate_bool_t ITaskBuilder::task_completed(void* this_ptr) | |
234 | { | ||
235 | ✗ | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
236 | ✗ | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
237 | ✗ | return static_cast<int>(obj->completed()); | |
238 | |||
239 | } | ||
240 | 1 | gate_result_t ITaskBuilder::task_get_result(void* this_ptr, gate_result_t* ptr_task_result, void const** ptr_task_data) | |
241 | { | ||
242 | 1 | result_t ret = results::Ok; | |
243 | 1 | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
244 | 1 | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
245 | |||
246 | 1 | result_t taskResult = results::Failed; | |
247 | 1 | void const* taskData = NULL; | |
248 | |||
249 | 1 | Task::StatusEnum status = obj->status(); | |
250 |
1/5✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1 | switch (status) |
251 | { | ||
252 | ✗ | case Task::Status_Prepared: | |
253 | case Task::Status_Running: | ||
254 | { | ||
255 | ✗ | taskResult = results::InvalidState; | |
256 | ✗ | break; | |
257 | } | ||
258 | 1 | case Task::Status_Completed: | |
259 | { | ||
260 | try | ||
261 | { | ||
262 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | taskData = obj->getResult(); |
263 | 1 | taskResult = results::Ok; | |
264 | } | ||
265 | ✗ | catch (Throwable const& xcpt) | |
266 | { | ||
267 | ✗ | taskResult = xcpt.getResult(); | |
268 | } | ||
269 | ✗ | catch (...) | |
270 | { | ||
271 | ✗ | taskResult = results::UnknownError; | |
272 | } | ||
273 | 1 | ret = results::Ok; | |
274 | 1 | break; | |
275 | } | ||
276 | ✗ | case Task::Status_Canceled: | |
277 | { | ||
278 | ✗ | taskResult = results::Canceled; | |
279 | ✗ | ret = results::Ok; | |
280 | ✗ | break; | |
281 | } | ||
282 | ✗ | case Task::Status_Failed: | |
283 | { | ||
284 | ✗ | taskResult = results::Failed; | |
285 | ✗ | ret = results::Ok; | |
286 | ✗ | break; | |
287 | } | ||
288 | } | ||
289 | |||
290 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_task_result) |
291 | { | ||
292 | 1 | *ptr_task_result = taskResult; | |
293 | } | ||
294 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_task_data) |
295 | { | ||
296 | 1 | *ptr_task_data = taskData; | |
297 | } | ||
298 | |||
299 | 1 | return ret; | |
300 | } | ||
301 | ✗ | gate_result_t ITaskBuilder::task_wait(void* this_ptr) | |
302 | { | ||
303 | ✗ | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
304 | ✗ | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
305 | try | ||
306 | { | ||
307 | ✗ | obj->wait(); | |
308 | ✗ | return results::Ok; | |
309 | } | ||
310 | ✗ | catch (Throwable const& xcpt) | |
311 | { | ||
312 | ✗ | return xcpt.getResult(); | |
313 | } | ||
314 | ✗ | catch (...) | |
315 | { | ||
316 | ✗ | return results::UnknownError; | |
317 | } | ||
318 | } | ||
319 | ✗ | gate_result_t ITaskBuilder::task_timed_wait(void* this_ptr, gate_uint32_t timeout_ms) | |
320 | { | ||
321 | ✗ | cpp_object* dispatcher = static_cast<cpp_object*>(this_ptr); | |
322 | ✗ | ITaskBuilder* obj = getInterface<ITaskBuilder>(dispatcher); | |
323 | try | ||
324 | { | ||
325 | ✗ | bool_t signaled = obj->waitFor(timeout_ms); | |
326 | ✗ | if (signaled) | |
327 | { | ||
328 | ✗ | return results::Ok; | |
329 | } | ||
330 | else | ||
331 | { | ||
332 | ✗ | return results::Timeout; | |
333 | } | ||
334 | } | ||
335 | ✗ | catch (Throwable const& xcpt) | |
336 | { | ||
337 | ✗ | return xcpt.getResult(); | |
338 | } | ||
339 | ✗ | catch (...) | |
340 | { | ||
341 | ✗ | return results::UnknownError; | |
342 | } | ||
343 | } | ||
344 | |||
345 | 2 | ITaskBuilder::VtblTask::VtblTask() | |
346 | { | ||
347 | 2 | obj_vtbl_t* this_ptr = reinterpret_cast<obj_vtbl_t*>(this); | |
348 | 2 | this_ptr->run = &ITaskBuilder::task_run; | |
349 | 2 | this_ptr->cancel = ITaskBuilder::task_cancel; | |
350 | 2 | this_ptr->get_status = ITaskBuilder::task_get_status; | |
351 | 2 | this_ptr->completed = ITaskBuilder::task_completed; | |
352 | 2 | this_ptr->get_result = ITaskBuilder::task_get_result; | |
353 | 2 | this_ptr->wait = ITaskBuilder::task_wait; | |
354 | 2 | this_ptr->timed_wait = ITaskBuilder::task_timed_wait; | |
355 | 2 | } | |
356 | |||
357 | ITaskBuilder::VtblTask ITaskBuilder::cpp_vtbl_task; | ||
358 | |||
359 | ✗ | ITaskBuilder::ITaskBuilder(obj_vtbl_t const* vtbl_ptr, char const* name) | |
360 | ✗ | : object_builder_t(vtbl_ptr, name) | |
361 | { | ||
362 | ✗ | } | |
363 | 1 | ITaskBuilder::ITaskBuilder() | |
364 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | : object_builder_t(&cpp_vtbl_task, GATE_INTERFACE_NAME_TASK) |
365 | { | ||
366 | 1 | } | |
367 | |||
368 | |||
369 | |||
370 | |||
371 | 1 | ITaskBase::ITaskBase() | |
372 | : statusvalue(static_cast<int32_t>(Task::Status_Prepared)), | ||
373 | completionsignal(false), | ||
374 | taskResult(results::Ok), | ||
375 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | taskData(NULL) |
376 | { | ||
377 | 1 | } | |
378 | |||
379 | 2 | ITaskBase::~ITaskBase() noexcept | |
380 | { | ||
381 | 2 | } | |
382 | |||
383 | ✗ | void ITaskBase::runImpl() | |
384 | { | ||
385 | ✗ | } | |
386 | ✗ | void ITaskBase::cancelImpl() | |
387 | { | ||
388 | ✗ | } | |
389 | |||
390 | 2 | static bool_t updateTaskStatus(AtomicInt& status, Task::StatusEnum fromStatus, Task::StatusEnum toStatus) | |
391 | { | ||
392 | 2 | int32_t oldStatus = status.changeIf(static_cast<int32_t>(fromStatus), static_cast<int32_t>(toStatus)); | |
393 | 2 | return oldStatus == static_cast<int32_t>(fromStatus); | |
394 | } | ||
395 | |||
396 | 1 | void ITaskBase::run() | |
397 | { | ||
398 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (!updateTaskStatus(this->statusvalue, Task::Status_Prepared, Task::Status_Running)) |
399 | { | ||
400 | ✗ | GATEXX_RAISE_EXCEPTION(results::InvalidState, "Cannot start task", 0); | |
401 | } | ||
402 | |||
403 | 1 | Task::StatusEnum nextStatus = Task::Status_Completed; | |
404 | 1 | result_t nextTaskResult = results::Ok; | |
405 | |||
406 | try | ||
407 | { | ||
408 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | this->runImpl(); |
409 | } | ||
410 | ✗ | catch (Throwable const& xcpt) | |
411 | { | ||
412 | ✗ | nextStatus = Task::Status_Failed; | |
413 | ✗ | nextTaskResult = xcpt.getResult(); | |
414 | } | ||
415 | ✗ | catch (...) | |
416 | { | ||
417 | ✗ | nextStatus = Task::Status_Failed; | |
418 | ✗ | nextTaskResult = results::UnknownException; | |
419 | } | ||
420 | |||
421 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (updateTaskStatus(this->statusvalue, Task::Status_Running, nextStatus)) |
422 | { | ||
423 | 1 | this->taskResult = nextTaskResult; | |
424 | 1 | this->completionsignal.set(); | |
425 | } | ||
426 | 1 | } | |
427 | |||
428 | 1 | void ITaskBase::setTaskData(void const* data) | |
429 | { | ||
430 | 1 | this->taskData = data; | |
431 | 1 | } | |
432 | |||
433 | |||
434 | ✗ | void ITaskBase::cancel() | |
435 | { | ||
436 | ✗ | if (updateTaskStatus(this->statusvalue, Task::Status_Prepared, Task::Status_Canceled)) | |
437 | { | ||
438 | ✗ | this->completionsignal.set(); | |
439 | } | ||
440 | ✗ | else if (updateTaskStatus(this->statusvalue, Task::Status_Running, Task::Status_Canceled)) | |
441 | { | ||
442 | try | ||
443 | { | ||
444 | ✗ | this->cancelImpl(); | |
445 | } | ||
446 | ✗ | catch (...) {} | |
447 | ✗ | this->completionsignal.set(); | |
448 | } | ||
449 | else | ||
450 | { | ||
451 | ✗ | GATEXX_RAISE_EXCEPTION(results::InvalidState, "Cannot cancel task", 0); | |
452 | } | ||
453 | ✗ | } | |
454 | 1 | Task::StatusEnum ITaskBase::status() | |
455 | { | ||
456 | 1 | return static_cast<Task::StatusEnum>(this->statusvalue.get()); | |
457 | } | ||
458 | ✗ | bool_t ITaskBase::completed() | |
459 | { | ||
460 | ✗ | Task::StatusEnum state = static_cast<Task::StatusEnum>(this->statusvalue.get()); | |
461 | ✗ | switch (state) | |
462 | { | ||
463 | ✗ | case Task::Status_Completed: | |
464 | case Task::Status_Canceled: | ||
465 | case Task::Status_Failed: | ||
466 | { | ||
467 | ✗ | return true; | |
468 | } | ||
469 | ✗ | default: | |
470 | { | ||
471 | ✗ | break; | |
472 | } | ||
473 | } | ||
474 | ✗ | return false; | |
475 | } | ||
476 | 1 | void const* ITaskBase::getResult() | |
477 | { | ||
478 | 1 | Task::StatusEnum state = static_cast<Task::StatusEnum>(this->statusvalue.get()); | |
479 |
1/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | switch (state) |
480 | { | ||
481 | 1 | case Task::Status_Completed: | |
482 | { | ||
483 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (GATE_FAILED(this->taskResult)) |
484 | { | ||
485 | ✗ | GATEXX_RAISE_EXCEPTION(this->taskResult, "Task execution failed", 0); | |
486 | } | ||
487 | else | ||
488 | { | ||
489 | 1 | return this->taskData; | |
490 | } | ||
491 | ✗ | break; | |
492 | } | ||
493 | ✗ | case Task::Status_Canceled: | |
494 | { | ||
495 | ✗ | GATEXX_RAISE_EXCEPTION(results::Canceled, "Task canceled", 0); | |
496 | ✗ | break; | |
497 | } | ||
498 | ✗ | case Task::Status_Failed: | |
499 | { | ||
500 | ✗ | GATEXX_RAISE_EXCEPTION(this->taskResult, "Task execution failed", 0); | |
501 | ✗ | break; | |
502 | } | ||
503 | ✗ | default: | |
504 | { | ||
505 | ✗ | GATEXX_RAISE_EXCEPTION(results::InvalidState, "Task not completed", 0); | |
506 | ✗ | break; | |
507 | } | ||
508 | } | ||
509 | ✗ | return NULL; | |
510 | } | ||
511 | ✗ | void ITaskBase::wait() | |
512 | { | ||
513 | ✗ | this->completionsignal.wait(); | |
514 | ✗ | } | |
515 | ✗ | bool ITaskBase::waitFor(uint32_t timeoutMs) | |
516 | { | ||
517 | ✗ | return this->completionsignal.waitFor(timeoutMs); | |
518 | } | ||
519 | |||
520 | |||
521 | |||
522 | class GATE_API_LOCAL TaskRunnableDispatcher : public ITaskBase | ||
523 | { | ||
524 | private: | ||
525 | Runnable runner; | ||
526 | |||
527 | public: | ||
528 | ✗ | TaskRunnableDispatcher(Runnable const& runnable) : runner(runnable) | |
529 | { | ||
530 | ✗ | } | |
531 | ✗ | virtual ~TaskRunnableDispatcher() noexcept {} | |
532 | ✗ | virtual void runImpl() | |
533 | { | ||
534 | ✗ | this->runner.run(); | |
535 | ✗ | } | |
536 | }; | ||
537 | |||
538 | ✗ | Task TaskBuilder::create(Runnable const& runnable) | |
539 | { | ||
540 | ✗ | ITaskBase* ptr_task = new TaskRunnableDispatcher(runnable); | |
541 | ✗ | return Task(ptr_task->c_impl()); | |
542 | } | ||
543 | |||
544 | |||
545 | } // end of namespace gate | ||
546 |