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.

improve child process event loop detection and polling

+48 -78
+3 -2
examples/demo/ephemeral_server.js
··· 1 1 let count = 0; 2 + const MAX_REQUESTS = 10; 2 3 3 4 console.log('starting on http://localhost:3000'); 4 5 ··· 8 9 count++; 9 10 ctx.res.json({ 10 11 request: count, 11 - remaining: 10 - count, 12 + remaining: Math.max(0, MAX_REQUESTS - count), 12 13 port: server.port 13 14 }); 14 15 15 - if (count >= 10) { 16 + if (count === MAX_REQUESTS) { 16 17 console.log('10 requests served, stopping'); 17 18 server.stop(); 18 19 }
+3 -3
include/arena.h
··· 103 103 void *decommit_start = (char *)base + new_pages; 104 104 size_t decommit_size = old_pages - new_pages; 105 105 106 - if (mprotect(decommit_start, decommit_size, PROT_NONE) == 0) return 0; 106 + if (mprotect(decommit_start, decommit_size, PROT_NONE) != 0) return -1; 107 107 #ifdef __APPLE__ 108 - madvise(decommit_start, decommit_size, MADV_FREE); 108 + if (madvise(decommit_start, decommit_size, MADV_FREE) != 0) return -1; 109 109 #else 110 - madvise(decommit_start, decommit_size, MADV_DONTNEED); 110 + if (madvise(decommit_start, decommit_size, MADV_DONTNEED) != 0) return -1; 111 111 #endif 112 112 return 0; 113 113 }
+2 -4
src/modules/child_process.c
··· 1148 1148 } 1149 1149 1150 1150 int has_pending_child_processes(void) { 1151 - return pending_children_head != NULL; 1151 + return pending_children_head != NULL || (cp_loop && uv_loop_alive(cp_loop)); 1152 1152 } 1153 1153 1154 1154 void child_process_poll_events(void) { 1155 - if (cp_loop && uv_loop_alive(cp_loop)) { 1156 - uv_run(cp_loop, UV_RUN_NOWAIT); 1157 - } 1155 + if (cp_loop && uv_loop_alive(cp_loop)) uv_run(cp_loop, UV_RUN_NOWAIT); 1158 1156 } 1159 1157 1160 1158 void child_process_gc_update_roots(GC_OP_VAL_ARGS) {
+7 -5
src/modules/events.c
··· 51 51 EventType **events = ant_calloc(sizeof(EventType *)); 52 52 if (!events) return NULL; 53 53 *events = NULL; 54 + 54 55 emitter_reg_t *reg = ant_calloc(sizeof(emitter_reg_t)); 55 - if (reg) { 56 - reg->events = events; 57 - reg->next = emitter_registry; 58 - emitter_registry = reg; 59 - } 56 + if (!reg) { free(events); return NULL; } 57 + 58 + reg->events = events; 59 + reg->next = emitter_registry; 60 + emitter_registry = reg; 61 + 60 62 js_set_slot(js, this_obj, SLOT_DATA, ANT_PTR(events)); 61 63 return events; 62 64 }
+31 -61
src/modules/process.c
··· 55 55 ProcessEventListener *listeners; 56 56 int listener_count; 57 57 int listener_capacity; 58 + int emitting; 59 + bool free_deferred; 58 60 UT_hash_handle hh; 59 61 } ProcessEventType; 60 62 ··· 205 207 return entry ? entry->name : NULL; 206 208 } 207 209 208 - static ProcessEventType *find_or_create_event_type(const char *event_type) { 210 + static ProcessEventType *find_or_create_event(ProcessEventType **table, const char *event_type) { 209 211 ProcessEventType *evt = NULL; 210 - HASH_FIND_STR(process_events, event_type, evt); 212 + HASH_FIND_STR(*table, event_type, evt); 211 213 212 214 if (evt == NULL) { 213 215 evt = malloc(sizeof(ProcessEventType)); 214 - evt->event_type = strdup(event_type); 215 - evt->listener_count = 0; 216 - evt->listener_capacity = INITIAL_LISTENER_CAPACITY; 217 - evt->listeners = malloc(sizeof(ProcessEventListener) * evt->listener_capacity); 218 - HASH_ADD_KEYPTR(hh, process_events, evt->event_type, strlen(evt->event_type), evt); 216 + *evt = (ProcessEventType){ 217 + .event_type = strdup(event_type), 218 + .emitting = 0, 219 + .listener_count = 0, 220 + .free_deferred = false, 221 + .listener_capacity = INITIAL_LISTENER_CAPACITY, 222 + .listeners = malloc(sizeof(ProcessEventListener) * INITIAL_LISTENER_CAPACITY), 223 + }; 224 + HASH_ADD_KEYPTR(hh, *table, evt->event_type, strlen(evt->event_type), evt); 219 225 } 220 226 221 227 return evt; ··· 234 240 235 241 static void free_event_type(ProcessEventType **events, ProcessEventType *evt) { 236 242 if (!evt) return; 243 + if (evt->emitting > 0) { evt->free_deferred = true; return; } 237 244 HASH_DEL(*events, evt); 238 245 239 246 free(evt->listeners); ··· 257 264 HASH_FIND_STR(process_events, event_type, evt); 258 265 259 266 if (evt == NULL || evt->listener_count == 0) return; 267 + evt->emitting++; int i = 0; 260 268 261 - int i = 0; 262 269 while (i < evt->listener_count) { 263 270 ProcessEventListener *listener = &evt->listeners[i]; 264 271 js_call(rt->js, listener->listener, args, nargs); ··· 268 275 evt->listeners[j] = evt->listeners[j + 1]; 269 276 } evt->listener_count--; 270 277 } else i++; 271 - } 278 + } evt->emitting--; 272 279 273 - if (evt->listener_count == 0) { 280 + if (evt->listener_count == 0 || evt->free_deferred) { 274 281 int signum = get_signal_number(event_type); 275 282 if (signum > 0) signal(signum, SIG_DFL); 276 - free_event_type(&process_events, evt); 283 + if (evt->emitting == 0) free_event_type(&process_events, evt); 277 284 } 278 285 } 279 286 ··· 285 292 } 286 293 } 287 294 288 - static ProcessEventType *find_or_create_stdin_event(const char *event_type) { 289 - ProcessEventType *evt = NULL; 290 - HASH_FIND_STR(stdin_events, event_type, evt); 291 - if (evt == NULL) { 292 - evt = malloc(sizeof(ProcessEventType)); 293 - evt->event_type = strdup(event_type); 294 - evt->listener_count = 0; 295 - evt->listener_capacity = INITIAL_LISTENER_CAPACITY; 296 - evt->listeners = malloc(sizeof(ProcessEventListener) * evt->listener_capacity); 297 - HASH_ADD_KEYPTR(hh, stdin_events, evt->event_type, strlen(evt->event_type), evt); 298 - } 299 - return evt; 300 - } 301 295 302 - static ProcessEventType *find_or_create_stdout_event(const char *event_type) { 303 - ProcessEventType *evt = NULL; 304 - HASH_FIND_STR(stdout_events, event_type, evt); 305 - if (evt == NULL) { 306 - evt = malloc(sizeof(ProcessEventType)); 307 - evt->event_type = strdup(event_type); 308 - evt->listener_count = 0; 309 - evt->listener_capacity = INITIAL_LISTENER_CAPACITY; 310 - evt->listeners = malloc(sizeof(ProcessEventListener) * evt->listener_capacity); 311 - HASH_ADD_KEYPTR(hh, stdout_events, evt->event_type, strlen(evt->event_type), evt); 312 - } 313 - return evt; 314 - } 315 296 316 297 static void emit_stdio_event(ProcessEventType **events, const char *event_type, jsval_t *args, int nargs) { 317 298 if (!rt->js) return; ··· 320 301 HASH_FIND_STR(*events, event_type, evt); 321 302 if (evt == NULL || evt->listener_count == 0) return; 322 303 304 + evt->emitting++; 323 305 int i = 0; 324 306 while (i < evt->listener_count) { 325 307 ProcessEventListener *listener = &evt->listeners[i]; 326 308 js_call(rt->js, listener->listener, args, nargs); 327 309 if (listener->once) { 328 - for (int j = i; j < evt->listener_count - 1; j++) { 310 + for (int j = i; j < evt->listener_count - 1; j++) 329 311 evt->listeners[j] = evt->listeners[j + 1]; 330 - } 331 312 evt->listener_count--; 332 313 } else i++; 333 - } 314 + } evt->emitting--; 334 315 335 - if (evt->listener_count == 0) free_event_type(events, evt); 316 + if ((evt->listener_count == 0 || evt->free_deferred) && evt->emitting == 0) 317 + free_event_type(events, evt); 336 318 } 337 319 338 320 static const char *stdin_escape_name(const char *seq, int len) { ··· 711 693 char *event = js_getstr(js, args[0], NULL); 712 694 if (!event || vtype(args[1]) != T_FUNC) return this_obj; 713 695 714 - ProcessEventType *evt = find_or_create_stdin_event(event); 696 + ProcessEventType *evt = find_or_create_event(&stdin_events, event); 715 697 if (!ensure_listener_capacity(evt)) return this_obj; 716 698 717 699 evt->listeners[evt->listener_count].listener = args[1]; ··· 776 758 char *event = js_getstr(js, args[0], NULL); 777 759 if (!event || vtype(args[1]) != T_FUNC) return this_obj; 778 760 779 - ProcessEventType *evt = find_or_create_stdout_event(event); 761 + ProcessEventType *evt = find_or_create_event(&stdout_events, event); 780 762 if (!ensure_listener_capacity(evt)) return this_obj; 781 763 782 764 evt->listeners[evt->listener_count].listener = args[1]; ··· 795 777 char *event = js_getstr(js, args[0], NULL); 796 778 if (!event || vtype(args[1]) != T_FUNC) return this_obj; 797 779 798 - ProcessEventType *evt = find_or_create_stdout_event(event); 780 + ProcessEventType *evt = find_or_create_event(&stdout_events, event); 799 781 if (!ensure_listener_capacity(evt)) return this_obj; 800 782 801 783 evt->listeners[evt->listener_count].listener = args[1]; ··· 863 845 return js_mknum(cols); 864 846 } 865 847 866 - static ProcessEventType *find_or_create_stderr_event(const char *event_type) { 867 - ProcessEventType *evt = NULL; 868 - HASH_FIND_STR(stderr_events, event_type, evt); 869 - if (evt == NULL) { 870 - evt = malloc(sizeof(ProcessEventType)); 871 - evt->event_type = strdup(event_type); 872 - evt->listener_count = 0; 873 - evt->listener_capacity = INITIAL_LISTENER_CAPACITY; 874 - evt->listeners = malloc(sizeof(ProcessEventListener) * evt->listener_capacity); 875 - HASH_ADD_KEYPTR(hh, stderr_events, evt->event_type, strlen(evt->event_type), evt); 876 - } 877 - return evt; 878 - } 848 + 879 849 880 850 static jsval_t js_stderr_write(ant_t *js, jsval_t *args, int nargs) { 881 851 if (nargs < 1) return js_false; ··· 894 864 char *event = js_getstr(js, args[0], NULL); 895 865 if (!event || vtype(args[1]) != T_FUNC) return this_obj; 896 866 897 - ProcessEventType *evt = find_or_create_stderr_event(event); 867 + ProcessEventType *evt = find_or_create_event(&stderr_events, event); 898 868 if (!ensure_listener_capacity(evt)) return this_obj; 899 869 900 870 evt->listeners[evt->listener_count].listener = args[1]; ··· 911 881 char *event = js_getstr(js, args[0], NULL); 912 882 if (!event || vtype(args[1]) != T_FUNC) return this_obj; 913 883 914 - ProcessEventType *evt = find_or_create_stderr_event(event); 884 + ProcessEventType *evt = find_or_create_event(&stderr_events, event); 915 885 if (!ensure_listener_capacity(evt)) return this_obj; 916 886 917 887 evt->listeners[evt->listener_count].listener = args[1]; ··· 1514 1484 signal(signum, process_signal_handler); 1515 1485 } 1516 1486 1517 - ProcessEventType *evt = find_or_create_event_type(event); 1487 + ProcessEventType *evt = find_or_create_event(&process_events, event); 1518 1488 if (!ensure_listener_capacity(evt)) { 1519 1489 return js_mkerr(js, "failed to allocate listener"); 1520 1490 } ··· 1540 1510 signal(signum, process_signal_handler); 1541 1511 } 1542 1512 1543 - ProcessEventType *evt = find_or_create_event_type(event); 1513 + ProcessEventType *evt = find_or_create_event(&process_events, event); 1544 1514 if (!ensure_listener_capacity(evt)) { 1545 1515 return js_mkerr(js, "failed to allocate listener"); 1546 1516 }
+2 -3
src/modules/url.c
··· 451 451 452 452 size_t buf_size = 1024; 453 453 char *buf = try_oom(buf_size); 454 - buf[0] = '?'; 455 - size_t pos = 1; 454 + size_t pos = 0; 456 455 457 456 for (jsoff_t i = 0; i < len; i++) { 458 457 jsval_t entry = js_arr_get(js, entries, i); ··· 470 469 if (!buf) { free(buf); return; } 471 470 } 472 471 473 - if (pos > 1) buf[pos++] = '&'; 472 + buf[pos] = pos == 0 ? '?' : '&'; pos++; 474 473 pos += sprintf(buf + pos, "%s=%s", ek, ev); 475 474 free(ek); free(ev); 476 475 }