build: finish cross-platform release tooling
This commit is contained in:
+71
-12
@@ -13,6 +13,7 @@
|
||||
#include "os_internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -503,19 +504,74 @@ int os_resolve_shell(char *out, size_t out_sz) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Per thread: parallel tool runs and sub-agents each watch their own flag. */
|
||||
static _Thread_local volatile int *g_run_cancel;
|
||||
static _Thread_local int g_run_timeout_s;
|
||||
/* Per thread: parallel tool runs and sub-agents each watch their own flag.
|
||||
* Thread keys rather than _Thread_local, which tcc does not implement; each
|
||||
* value fits in the key's pointer slot, so nothing is allocated. */
|
||||
#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 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();
|
||||
return TRUE;
|
||||
}
|
||||
static void *run_key_get(DWORD *key) {
|
||||
InitOnceExecuteOnce(&g_run_once, run_keys_init, NULL, NULL);
|
||||
if (*key == TLS_OUT_OF_INDEXES)
|
||||
return NULL;
|
||||
DWORD err = GetLastError(); /* TlsGetValue clears it */
|
||||
void *v = TlsGetValue(*key);
|
||||
SetLastError(err);
|
||||
return v;
|
||||
}
|
||||
static void run_key_set(DWORD *key, void *v) {
|
||||
InitOnceExecuteOnce(&g_run_once, run_keys_init, NULL, NULL);
|
||||
if (*key != TLS_OUT_OF_INDEXES)
|
||||
TlsSetValue(*key, v);
|
||||
}
|
||||
#else
|
||||
static pthread_once_t g_run_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t g_key_cancel, g_key_timeout;
|
||||
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;
|
||||
}
|
||||
static void *run_key_get(pthread_key_t *key) {
|
||||
pthread_once(&g_run_once, run_keys_init);
|
||||
return g_run_keys_ok ? pthread_getspecific(*key) : NULL;
|
||||
}
|
||||
static void run_key_set(pthread_key_t *key, void *v) {
|
||||
pthread_once(&g_run_once, run_keys_init);
|
||||
if (g_run_keys_ok)
|
||||
pthread_setspecific(*key, v);
|
||||
}
|
||||
#endif
|
||||
|
||||
void os_set_cancel_flag(volatile int *flag) { g_run_cancel = flag; }
|
||||
static volatile int *run_cancel(void) {
|
||||
return (volatile int *)run_key_get(&g_key_cancel);
|
||||
}
|
||||
static int run_timeout(void) {
|
||||
return (int)(intptr_t)run_key_get(&g_key_timeout);
|
||||
}
|
||||
|
||||
void os_set_run_timeout(int seconds) { g_run_timeout_s = seconds; }
|
||||
void os_set_cancel_flag(volatile int *flag) {
|
||||
run_key_set(&g_key_cancel, (void *)(uintptr_t)flag);
|
||||
}
|
||||
|
||||
int os_get_run_timeout(void) { return g_run_timeout_s; }
|
||||
void os_set_run_timeout(int seconds) {
|
||||
run_key_set(&g_key_timeout, (void *)(intptr_t)seconds);
|
||||
}
|
||||
|
||||
int os_get_run_timeout(void) { return run_timeout(); }
|
||||
|
||||
int os_run_timeout_effective(void) {
|
||||
if (g_run_timeout_s > 0)
|
||||
return g_run_timeout_s;
|
||||
int t = run_timeout();
|
||||
if (t > 0)
|
||||
return t;
|
||||
const char *e = getenv("CST_SHELL_TIMEOUT");
|
||||
if (e && atoi(e) > 0)
|
||||
return atoi(e);
|
||||
@@ -693,8 +749,8 @@ int os_run_capture_ex(const char *cwd, const char *const argv[],
|
||||
}
|
||||
/* Checked on every pass, so a chatty command still stops promptly. */
|
||||
if (!reaped && !killed &&
|
||||
((g_run_cancel && *g_run_cancel) || (deadline > 0 && now > deadline))) {
|
||||
killed = (g_run_cancel && *g_run_cancel) ? 2 : 1;
|
||||
(os_cancel_requested() || (deadline > 0 && now > deadline))) {
|
||||
killed = os_cancel_requested() ? 2 : 1;
|
||||
killed_at = now;
|
||||
kill(-pid, SIGTERM);
|
||||
}
|
||||
@@ -900,9 +956,12 @@ void os_run_parallel(os_task_fn fn, void *const args[], int n) {
|
||||
free(tasks);
|
||||
}
|
||||
|
||||
int os_cancel_requested(void) { return g_run_cancel && *g_run_cancel; }
|
||||
int os_cancel_requested(void) {
|
||||
volatile int *c = run_cancel();
|
||||
return c && *c;
|
||||
}
|
||||
|
||||
volatile int *os_get_cancel_flag(void) { return g_run_cancel; }
|
||||
volatile int *os_get_cancel_flag(void) { return run_cancel(); }
|
||||
|
||||
#ifndef _WIN32
|
||||
int os_proc_spawn(const char *cwd, const char *const argv[],
|
||||
|
||||
Reference in New Issue
Block a user