feat: add v2 task control and asynchronous isolated workers

This commit is contained in:
WHC
2026-10-20 14:46:57 +08:00
parent 143dba203b
commit d971cb02b0
26 changed files with 1590 additions and 66 deletions
+13 -4
View File
@@ -510,12 +510,14 @@ int os_resolve_shell(char *out, size_t out_sz) {
#ifdef _WIN32
static INIT_ONCE g_run_once = INIT_ONCE_STATIC_INIT;
static DWORD g_key_cancel = TLS_OUT_OF_INDEXES, g_key_timeout = TLS_OUT_OF_INDEXES;
static DWORD g_key_output = TLS_OUT_OF_INDEXES;
static BOOL CALLBACK run_keys_init(PINIT_ONCE once, PVOID param, PVOID *ctx) {
(void)once;
(void)param;
(void)ctx;
g_key_cancel = TlsAlloc();
g_key_timeout = TlsAlloc();
g_key_output = TlsAlloc();
return TRUE;
}
static void *run_key_get(DWORD *key) {
@@ -534,11 +536,12 @@ static void run_key_set(DWORD *key, void *v) {
}
#else
static pthread_once_t g_run_once = PTHREAD_ONCE_INIT;
static pthread_key_t g_key_cancel, g_key_timeout;
static pthread_key_t g_key_cancel, g_key_timeout, g_key_output;
static int g_run_keys_ok;
static void run_keys_init(void) {
g_run_keys_ok = pthread_key_create(&g_key_cancel, NULL) == 0 &&
pthread_key_create(&g_key_timeout, NULL) == 0;
pthread_key_create(&g_key_timeout, NULL) == 0 &&
pthread_key_create(&g_key_output, NULL) == 0;
}
static void *run_key_get(pthread_key_t *key) {
pthread_once(&g_run_once, run_keys_init);
@@ -561,6 +564,11 @@ static int run_timeout(void) {
void os_set_cancel_flag(volatile int *flag) {
run_key_set(&g_key_cancel, (void *)(uintptr_t)flag);
}
void os_set_output_observer(os_output_observer_t *observer) { run_key_set(&g_key_output, observer); }
void os_observe_output(const char *data, size_t n) {
os_output_observer_t *o = run_key_get(&g_key_output);
if (o && o->write) o->write(data, n, o->userdata);
}
void os_set_run_timeout(int seconds) {
run_key_set(&g_key_timeout, (void *)(intptr_t)seconds);
@@ -730,9 +738,10 @@ int os_run_capture_ex(const char *cwd, const char *const argv[],
ssize_t n = read(pipefd[0], tmp, sizeof(tmp));
if (n == 0)
break; /* every writer closed */
if (n > 0)
if (n > 0) {
os_cap_append(&buf, &len, &cap, max_out, tmp, (size_t)n, &truncated);
else if (errno != EINTR && errno != EAGAIN)
os_observe_output(tmp, (size_t)n);
} else if (errno != EINTR && errno != EAGAIN)
break;
}
double now = os_now_ms();