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.

add signal handling and sleep functions

+70 -58
+23
examples/demo/signals.js
··· 1 + import { constants } from 'ant:os'; 2 + 3 + let counter = 0; 4 + 5 + Ant.signal(constants.signals.SIGINT, function (signum) { 6 + console.log('\nreceived SIGINT (signal', signum, ')'); 7 + console.log('counter reached:', counter); 8 + console.log('shutting down gracefully...'); 9 + }); 10 + 11 + Ant.signal(constants.signals.SIGTERM, function (signum) { 12 + console.log('\nreceived SIGTERM (signal', signum, ')'); 13 + console.log('counter reached:', counter); 14 + console.log('terminating...'); 15 + }); 16 + 17 + console.log('starting counter...'); 18 + console.log('press Ctrl+C to trigger graceful shutdown'); 19 + 20 + for (;;) { 21 + counter++; Ant.usleep(5000); 22 + if (counter % 1000000 === 0) console.log('counter:', counter); 23 + }
+1 -1
meson.build
··· 96 96 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 97 97 98 98 version_conf = configuration_data() 99 - version_conf.set('ANT_VERSION', '0.3.2.27') 99 + version_conf.set('ANT_VERSION', '0.3.2.28') 100 100 version_conf.set('ANT_GIT_HASH', git_hash) 101 101 version_conf.set('ANT_BUILD_DATE', build_date) 102 102
+46 -34
src/modules/builtin.c
··· 2 2 #include <stdio.h> 3 3 #include <signal.h> 4 4 #include <string.h> 5 + #include <unistd.h> 6 + #include <time.h> 7 + #include <errno.h> 5 8 6 9 #include "ant.h" 7 10 #include "gc.h" ··· 11 14 static struct { 12 15 struct js *js; 13 16 jsval_t handler; 14 - } signal_handlers[32] = {0}; 17 + } signal_handlers[NSIG] = {0}; 15 18 16 19 static void general_signal_handler(int signum) { 17 - if (signum >= 0 && signum < 32 && signal_handlers[signum].js != NULL) { 18 - struct js *js = signal_handlers[signum].js; 19 - jsval_t handler = signal_handlers[signum].handler; 20 - 21 - if (js_type(handler) != JS_UNDEF) { 22 - jsval_t sig_num = js_mknum(signum); 23 - jsval_t args[1] = {sig_num}; 24 - js_call(js, handler, args, 1); 25 - } 20 + if (signum < 0 || signum >= NSIG) return; 21 + struct js *js = signal_handlers[signum].js; 22 + jsval_t handler = signal_handlers[signum].handler; 23 + 24 + if (js && js_type(handler) != JS_UNDEF) { 25 + jsval_t args[] = {js_mknum(signum)}; 26 + js_call(js, handler, args, 1); 26 27 } 27 28 28 29 exit(0); ··· 30 31 31 32 // Ant.signal(signal, handler) 32 33 static jsval_t js_signal(struct js *js, jsval_t *args, int nargs) { 33 - if (nargs < 2) { 34 - fprintf(stderr, "Error: Ant.signal() requires 2 arguments (signal, handler)\n"); 35 - return js_mkundef(); 36 - } 37 - 38 - char *signal_name = js_getstr(js, args[0], NULL); 39 - if (signal_name == NULL) { 40 - return js_mkerr(js, "signal name must be a string"); 41 - } 34 + if (nargs < 2) return js_mkerr(js, "Ant.signal() requires 2 arguments"); 42 35 43 - int signum = -1; 44 - if (strcmp(signal_name, "SIGINT") == 0 || strcmp(signal_name, "sigint") == 0) { 45 - signum = SIGINT; 46 - } else if (strcmp(signal_name, "SIGTERM") == 0 || strcmp(signal_name, "sigterm") == 0) { 47 - signum = SIGTERM; 48 - } else if (strcmp(signal_name, "SIGHUP") == 0 || strcmp(signal_name, "sighup") == 0) { 49 - signum = SIGHUP; 50 - } else if (strcmp(signal_name, "SIGUSR1") == 0 || strcmp(signal_name, "sigusr1") == 0) { 51 - signum = SIGUSR1; 52 - } else if (strcmp(signal_name, "SIGUSR2") == 0 || strcmp(signal_name, "sigusr2") == 0) { 53 - signum = SIGUSR2; 54 - } else { 55 - return js_mkerr(js, "unsupported signal: %s", signal_name); 36 + int signum = (int)js_getnum(args[0]); 37 + if (signum <= 0 || signum >= NSIG) { 38 + return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid signal number: %d", signum); 56 39 } 57 40 58 41 signal_handlers[signum].js = js; ··· 106 89 return result; 107 90 } 108 91 109 - // Ant.raw.typeof() 92 + // Ant.raw.typeof(jsval_t) 110 93 static jsval_t js_raw_typeof(struct js *js, jsval_t *args, int nargs) { 111 94 if (nargs < 1) return js_mkerr(js, "Ant.raw.typeof() requires 1 argument"); 112 95 const uint8_t type = vtype(args[0]); 113 96 return js_mknum((double)type); 114 97 } 115 98 99 + // Ant.sleep(seconds) 100 + static jsval_t js_sleep(struct js *js, jsval_t *args, int nargs) { 101 + if (nargs < 1) return js_mkerr(js, "Ant.sleep() requires 1 argument"); 102 + unsigned int seconds = (unsigned int)js_getnum(args[0]); 103 + sleep(seconds); 104 + return js_mkundef(); 105 + } 106 + 107 + // Ant.msleep(milliseconds) 108 + static jsval_t js_msleep(struct js *js, jsval_t *args, int nargs) { 109 + if (nargs < 1) return js_mkerr(js, "Ant.msleep() requires 1 argument"); 110 + long ms = (long)js_getnum(args[0]); 111 + struct timespec ts = { .tv_sec = ms / 1000, .tv_nsec = (ms % 1000) * 1000000 }; 112 + struct timespec rem; 113 + while (nanosleep(&ts, &rem) == -1 && errno == EINTR) ts = rem; 114 + return js_mkundef(); 115 + } 116 + 117 + // Ant.usleep(microseconds) 118 + static jsval_t js_usleep(struct js *js, jsval_t *args, int nargs) { 119 + if (nargs < 1) return js_mkerr(js, "Ant.usleep() requires 1 argument"); 120 + useconds_t us = (useconds_t)js_getnum(args[0]); 121 + usleep(us); 122 + return js_mkundef(); 123 + } 124 + 116 125 // Ant.stats() 117 126 static jsval_t js_stats_fn(struct js *js, jsval_t *args, int nargs) { 118 127 (void) args; (void) nargs; ··· 139 148 js_set(js, ant_obj, "gc", js_mkfun(js_gc_trigger)); 140 149 js_set(js, ant_obj, "alloc", js_mkfun(js_alloc)); 141 150 js_set(js, ant_obj, "stats", js_mkfun(js_stats_fn)); 142 - js_set(js, rt->ant_obj, "signal", js_mkfun(js_signal)); 151 + js_set(js, ant_obj, "signal", js_mkfun(js_signal)); 152 + js_set(js, ant_obj, "sleep", js_mkfun(js_sleep)); 153 + js_set(js, ant_obj, "msleep", js_mkfun(js_msleep)); 154 + js_set(js, ant_obj, "usleep", js_mkfun(js_usleep)); 143 155 144 156 jsval_t raw_obj = js_mkobj(js); 145 157 js_set(js, raw_obj, "typeof", js_mkfun(js_raw_typeof));
-23
tests/signals.cjs
··· 1 - let counter = 0; 2 - 3 - Ant.signal('sigint', function (signum) { 4 - console.log('\nReceived SIGINT (signal', signum, ')'); 5 - console.log('Counter reached:', counter); 6 - console.log('Shutting down gracefully...'); 7 - }); 8 - 9 - Ant.signal('sigterm', function (signum) { 10 - console.log('\nReceived SIGTERM (signal', signum, ')'); 11 - console.log('Counter reached:', counter); 12 - console.log('Terminating...'); 13 - }); 14 - 15 - console.log('Starting counter...'); 16 - console.log('Press Ctrl+C to trigger graceful shutdown'); 17 - 18 - for (;;) { 19 - counter++; 20 - if (counter % 1000000 === 0) { 21 - console.log('Counter:', counter); 22 - } 23 - }