MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

integrate libuv event loop with reactor for async server

+49 -48
+3
include/modules/navigator.h
··· 1 1 #ifndef NAVIGATOR_H 2 2 #define NAVIGATOR_H 3 3 4 + #include "gc.h" 5 + 4 6 void init_navigator_module(void); 7 + void navigator_gc_update_roots(GC_OP_VAL_ARGS); 5 8 6 9 #endif
+3
include/modules/server.h
··· 1 1 #ifndef SERVER_H 2 2 #define SERVER_H 3 3 4 + #include "gc.h" 5 + 4 6 void init_server_module(void); 7 + void server_gc_update_roots(GC_OP_VAL_ARGS); 5 8 6 9 #endif
+4 -1
include/reactor.h
··· 23 23 24 24 #define UV_CHECK_ALIVE uv_loop_alive(uv_default_loop()) 25 25 26 - void js_poll_events(ant_t *js) ; 26 + typedef void (*reactor_poll_hook_t)(void *data); 27 + void js_reactor_set_poll_hook(reactor_poll_hook_t hook, void *data); 28 + 29 + void js_poll_events(ant_t *js); 27 30 void js_run_event_loop(ant_t *js); 28 31 29 32 #endif
+4
src/ant.c
··· 53 53 #include "modules/json.h" 54 54 #include "modules/buffer.h" 55 55 #include "modules/collections.h" 56 + #include "modules/navigator.h" 57 + #include "modules/server.h" 56 58 #include "esm/remote.h" 57 59 58 60 #define D(x) ((double)(x)) ··· 22450 22452 child_process_gc_update_roots(op_val, c); 22451 22453 readline_gc_update_roots(op_val, c); 22452 22454 process_gc_update_roots(op_val, c); 22455 + navigator_gc_update_roots(op_val, c); 22456 + server_gc_update_roots(op_val, c); 22453 22457 22454 22458 for (int i = 0; i < c->js->for_let_stack_len; i++) { 22455 22459 op_val(c, &c->js->for_let_stack[i].body_scope);
+7
src/modules/navigator.c
··· 390 390 js_set(js, navigator_obj, get_toStringTag_sym_key(), js_mkstr(js, "Navigator", 9)); 391 391 js_set(js, js_glob(js), "navigator", navigator_obj); 392 392 } 393 + 394 + void navigator_gc_update_roots(GC_OP_VAL_ARGS) { 395 + for (lock_request_t *req = pending_requests; req; req = req->next) { 396 + op_val(ctx, &req->callback); 397 + op_val(ctx, &req->promise); 398 + } 399 + }
+18 -47
src/modules/server.c
··· 17 17 #include "internal.h" 18 18 19 19 #include "modules/server.h" 20 - #include "modules/timer.h" 21 20 #include "modules/json.h" 22 21 23 22 #define MAX_WRITE_HANDLES 1000 ··· 97 96 uv_buf_t buf; 98 97 } write_req_t; 99 98 100 - static uv_loop_t *g_loop = NULL; 101 - static int g_loop_initialized = 0; 102 - static uv_timer_t g_js_timer; 103 - static int g_request_count = 0; 99 + static http_server_t *g_server = NULL; 104 100 105 101 static void server_signal_handler(int signum) { 106 - (void)signum; 107 - if (g_loop_initialized && g_loop) uv_stop(g_loop); 108 - exit(0); 109 - } 110 - 111 - static void on_js_timer(uv_timer_t *handle) { 112 - struct js *js = (struct js*)handle->data; 113 - if (js && has_pending_immediates()) process_immediates(js); 102 + uv_stop(uv_default_loop()); exit(0); 114 103 } 115 104 116 105 static int parse_accept_encoding(const char *buffer, size_t len) { ··· 700 689 http_server_t *server = client->server; 701 690 jsval_t result = js_mkundef(); 702 691 703 - if (++g_request_count >= 1000 * 10) { 704 - js_gc_compact(server->js); 705 - g_request_count = 0; 706 - 707 - server->store_obj = js_get_slot(server->js, rt->ant_obj, SLOT_DATA); 708 - server->handler = js_get_slot(server->js, server->store_obj, SLOT_DATA); 709 - } 710 - 711 692 response_ctx_t *res_ctx = malloc(sizeof(response_ctx_t)); 712 693 if (!res_ctx) { 713 694 fprintf(stderr, "Failed to allocate response context\n"); ··· 950 931 951 932 server->store_obj = js_mkobj(js); 952 933 server->handler = (nargs >= 2) ? args[1] : js_mkundef(); 934 + g_server = server; 953 935 954 - js_set_slot(js, server->store_obj, SLOT_DATA, server->handler); 955 - js_set_slot(js, rt->ant_obj, SLOT_DATA, server->store_obj); 956 - 957 - if (!g_loop_initialized) { 958 - g_loop = uv_default_loop(); 959 - g_loop_initialized = 1; 960 - 961 - signal(SIGINT, server_signal_handler); 962 - signal(SIGTERM, server_signal_handler); 963 - } 936 + uv_loop_t *loop = uv_default_loop(); 937 + server->loop = loop; 964 938 965 - server->loop = g_loop; 939 + signal(SIGINT, server_signal_handler); 940 + signal(SIGTERM, server_signal_handler); 966 941 967 - uv_tcp_init(g_loop, &server->server); 942 + uv_tcp_init(loop, &server->server); 968 943 server->server.data = server; 969 944 970 945 struct sockaddr_in addr; ··· 985 960 } 986 961 987 962 server->pending_responses = NULL; 988 - uv_timer_init(g_loop, &g_js_timer); 989 - 990 - g_js_timer.data = js; 991 - rt->flags |= ANT_RUNTIME_EXT_EVENT_LOOP; 992 - 993 - while (uv_loop_alive(g_loop)) { 994 - if (has_pending_immediates()) { 995 - uv_timer_start(&g_js_timer, on_js_timer, 0, 0); 996 - } else uv_timer_stop(&g_js_timer); 997 - 998 - uv_run(g_loop, UV_RUN_ONCE); 999 - js_poll_events(js); 1000 - check_pending_responses(server); 1001 - } 963 + js_reactor_set_poll_hook( 964 + (reactor_poll_hook_t)check_pending_responses, server 965 + ); js_run_event_loop(js); 1002 966 1003 967 return js_mknum(1); 1004 968 } ··· 1006 970 void init_server_module() { 1007 971 js_set(rt->js, rt->ant_obj, "serve", js_mkfun(js_serve)); 1008 972 } 973 + 974 + void server_gc_update_roots(GC_OP_VAL_ARGS) { 975 + if (g_server) { 976 + op_val(ctx, &g_server->handler); 977 + op_val(ctx, &g_server->store_obj); 978 + } 979 + }
+10
src/reactor.c
··· 12 12 #include "modules/readline.h" 13 13 #include "modules/process.h" 14 14 15 + static reactor_poll_hook_t g_poll_hook = NULL; 16 + static void *g_poll_hook_data = NULL; 17 + 18 + void js_reactor_set_poll_hook(reactor_poll_hook_t hook, void *data) { 19 + g_poll_hook = hook; 20 + g_poll_hook_data = data; 21 + } 22 + 15 23 void js_poll_events(ant_t *js) { 16 24 coros_this_tick = 0; 17 25 ··· 42 50 js_gc_compact(js); 43 51 js->gc_alloc_since = 0; 44 52 } 53 + 54 + if (g_poll_hook) g_poll_hook(g_poll_hook_data); 45 55 } 46 56 47 57 static inline work_flags_t get_pending_work(void) {