1 contributor
118 lines2.2 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,
5 months ago
49
size_t stack_size,
8 months ago
37
50
Task_Entry entry,
51
void *param
52
){
53
assert(Coroutine_IsStarted());
54
Future_ctor(&tsk->base);
55
tsk->base.vfptrs = &Task_vfptrs;
56
tsk->entry = entry;
57
tsk->param = param;
5 months ago
58
tsk->cor = Coroutine_New(stack_size, Task_entry);
8 months ago
37
59
tsk->awaiting_future = NULL;
60
tsk->canceled = false;
61
tsk->cancel_value = NULL;
62
if (current_task){
63
Coroutine_Continue(tsk->cor, tsk, false);
64
}
65
}
66
67
68
void Task_dtor(
69
Task *tsk
70
){
71
Coroutine_Delete(tsk->cor);
72
Future_dtor(&tsk->base);
73
}
74
75
76
Task *Task_New(
5 months ago
77
size_t stack_size,
8 months ago
37
78
Task_Entry entry,
79
void *param
80
){
81
Task *tsk = malloc(sizeof(Task));
5 months ago
82
Task_ctor(tsk, stack_size, entry, param);
8 months ago
37
83
return tsk;
84
}
85
86
87
void Task_Delete(
88
Task *tsk
89
){
90
Future_Delete(&tsk->base);
91
}
92
93
94
void Task_Cancel(
95
Task *tsk,
96
void *cancel_value
97
){
98
if (!tsk->canceled){
99
tsk->canceled = true;
100
tsk->cancel_value = cancel_value;
101
Future *awaiting_future = tsk->awaiting_future;
102
if (awaiting_future){
103
Future_SetResult(awaiting_future, true, NULL);
104
}
105
}
106
}
107
108
5 months ago
109
bool Task_Run(size_t stack_size, Task_Entry start, void *value, void **res){
8 months ago
37
110
assert(current_task == NULL);
111
Task tsk;
5 months ago
112
Task_ctor(&tsk, stack_size, start, value);
8 months ago
37
113
Coroutine_Run_Coroutine(tsk.cor, &tsk);
114
bool canceled = Future_GetResult(&tsk.base, res);
115
Task_dtor(&tsk);
116
return canceled;
117
}
118