1 contributor
116 lines2.1 KB
Newer
Older
-
+
commited
{line.log.rev}
on
8 months ago
37
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
15
static 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
28
Future_vfptrs_t Task_vfptrs = {
29
(void(*)(Future *fut))&Task_dtor,
30
&_Future_Await,
31
&_Task_SetResult,
32
};
33
34
35
static 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
47
void 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
67
void Task_dtor(
68
Task *tsk
69
){
70
Coroutine_Delete(tsk->cor);
71
Future_dtor(&tsk->base);
72
}
73
74
75
Task *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
85
void Task_Delete(
86
Task *tsk
87
){
88
Future_Delete(&tsk->base);
89
}
90
91
92
void 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
107
bool 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