1 contributor
116 lines2.1 KB
1#include "task.h"
2#include <assert.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <time.h>
6#include <errno.h>
7#include <math.h>
8#include <string.h>
9#include "timespec_utils.h"
10
11
12_Cor_thread_local Task *current_task;
13
14
15static void _Task_SetResult(
16 Future *fut,
17 bool canceled,
18 void *res
19){
20 (void)fut;
21 (void)canceled;
22 (void)res;
23 // only the task can set it's future's result
24 assert(false);
25}
26
27
28Future_vfptrs_t Task_vfptrs = {
29 (void(*)(Future *fut))&Task_dtor,
30 &_Future_Await,
31 &_Task_SetResult,
32};
33
34
35static void *Task_entry(void *me){
36 Task *tsk = (Task *)me;
37 void *res = NULL;
38 assert(current_task == NULL);
39 current_task = tsk;
40 bool canceled = tsk->entry(tsk->param, &res);
41 current_task = NULL;
42 _Future_SetResult(&tsk->base, canceled, res);
43 return res;
44}
45
46
47void Task_ctor(
48 Task *tsk,
49 Task_Entry entry,
50 void *param
51){
52 assert(Coroutine_IsStarted());
53 Future_ctor(&tsk->base);
54 tsk->base.vfptrs = &Task_vfptrs;
55 tsk->entry = entry;
56 tsk->param = param;
57 tsk->cor = Coroutine_New(Task_entry);
58 tsk->awaiting_future = NULL;
59 tsk->canceled = false;
60 tsk->cancel_value = NULL;
61 if (current_task){
62 Coroutine_Continue(tsk->cor, tsk, false);
63 }
64}
65
66
67void Task_dtor(
68 Task *tsk
69){
70 Coroutine_Delete(tsk->cor);
71 Future_dtor(&tsk->base);
72}
73
74
75Task *Task_New(
76 Task_Entry entry,
77 void *param
78){
79 Task *tsk = malloc(sizeof(Task));
80 Task_ctor(tsk, entry, param);
81 return tsk;
82}
83
84
85void Task_Delete(
86 Task *tsk
87){
88 Future_Delete(&tsk->base);
89}
90
91
92void Task_Cancel(
93 Task *tsk,
94 void *cancel_value
95){
96 if (!tsk->canceled){
97 tsk->canceled = true;
98 tsk->cancel_value = cancel_value;
99 Future *awaiting_future = tsk->awaiting_future;
100 if (awaiting_future){
101 Future_SetResult(awaiting_future, true, NULL);
102 }
103 }
104}
105
106
107bool Task_Run(Task_Entry start, void *value, void **res){
108 assert(current_task == NULL);
109 Task tsk;
110 Task_ctor(&tsk, start, value);
111 Coroutine_Run_Coroutine(tsk.cor, &tsk);
112 bool canceled = Future_GetResult(&tsk.base, res);
113 Task_dtor(&tsk);
114 return canceled;
115}
116