forked from ccxvii/mujs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjstask.c
88 lines (77 loc) · 1.72 KB
/
jstask.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "jsi.h"
void free_task(micro_task *task)
{
list_del(&task->link);
free(task->fn);
free(task);
}
void js_freetask(js_Loop *loop)
{
struct list_head *el, *el1;
list_for_each_safe(el, el1, &loop->micro_list)
{
micro_task *task = list_entry(el, micro_task, link);
free_task(task);
}
}
void execute_jobs(js_State *J)
{
struct list_head *el, *el1;
micro_task *task;
js_Loop *loop;
loop = js_getcontext(J);
list_for_each_safe(el, el1, &loop->micro_list)
{
task = list_entry(el, micro_task, link);
js_pushobject(J, task->fn);
js_pushundefined(J);
if(js_pcall(J, 0))
{
fprintf(stderr, "%s\n", js_trystring(J, -1, "Error"));
js_pop(J, 1);
}
free_task(task);
}
}
void micro_cb(int fd, short flags, void *userdata)
{
js_State *J = (js_State *)userdata;
execute_jobs(J);
}
static void jsB_queueMicrotask(js_State *J)
{
js_Loop *loop;
int top;
micro_task *task;
struct timeval tv;
loop = js_getcontext(J);
top = js_gettop(J);
if(top < 2)
{
js_typeerror(J, "需要一个函数作为参数");
}
if(!js_iscallable(J, -1))
{
js_typeerror(J, "第一个参数不是函数");
}
js_Object *fn = js_toobject(J, -1);
task = malloc(sizeof(micro_task));
task->fn = malloc(sizeof(js_Object));
memcpy(task->fn, fn, sizeof(js_Object));
list_add_tail(&task->link, &loop->micro_list);
tv.tv_sec = 0;
tv.tv_usec = 0;
evtimer_del(loop->micro_event);
evtimer_add(loop->micro_event, &tv);
js_pushundefined(J);
}
void jsB_inittask(js_State *J)
{
js_newcfunction(J, jsB_queueMicrotask, "queueMicrotask", 0);
js_setglobal(J, "queueMicrotask");
}
void jsB_initjob(js_Loop *loop)
{
loop->micro_event = event_new(loop->base, -1, EV_TIMEOUT | EV_PERSIST, micro_cb, loop->J);
init_list_head(&loop->micro_list);
}