diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c
index b0f1c2a..98036a8 100644
--- a/src/builder/b-nspawn.c
+++ b/src/builder/b-nspawn.c
@@ -89,9 +89,9 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
switch (reason) {
case LWS_CALLBACK_RAW_CLOSE_FILE:
- lwsl_info("%s: RAW_CLOSE_FILE at %llu, wsi %p: fd: %d, stdfd: %d\n",
- __func__, (unsigned long long)lws_now_usecs(), wsi,
- lws_get_socket_fd(wsi), lws_spawn_get_stdfd(wsi));
+ lwsl_info("%s: stdwsi CLOSE, ns %p, lsp: %p, wsi: %p, fd: %d, stdfd: %d\n",
+ __func__, op ? op->ns : NULL, op ? op->lsp : NULL,
+ wsi, lws_get_socket_fd(wsi), lws_spawn_get_stdfd(wsi));
ilen = lws_snprintf((char *)buf, sizeof(buf), "Stdwsi %d close\n", lws_spawn_get_stdfd(wsi));
if (ns) {
@@ -103,7 +103,11 @@ callback_sai_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
}
if (op && op->lsp) {
- lws_spawn_stdwsi_closed(op->lsp, wsi);
+ if (lws_spawn_stdwsi_closed(op->lsp, wsi) &&
+ ns->reap_cb_called) {
+ lwsl_notice("%s: freeing op from stdwsi_cb\n", __func__);
+ free(op);
+ }
if (ns)
lws_cancel_service(ns->builder->context);
}
@@ -338,9 +342,15 @@ skip:
saib_task_grace(ns);
saib_set_ns_state(ns, NSSTATE_DONE);
+ ns->reap_cb_called = 1;
+
if (ns)
ns->op = NULL;
- free(op);
+
+ if (!op->lsp || lws_spawn_get_stdwsi_open_count(op->lsp) == 0) {
+ lwsl_notice("%s: freeing op from reap_cb\n", __func__);
+ free(op);
+ }
return;
@@ -589,6 +599,7 @@ saib_spawn_script(struct sai_nspawn *ns)
memset(op, 0, sizeof(*op));
op->ns = ns;
+ ns->reap_cb_called = 0;
ns->op = op;
#if defined(WIN32)
op->spawn = _strdup(one_step);
diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index 54608ca..25db3e0 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -139,7 +139,11 @@ struct sai_builder {
uint64_t disk_total_kib;
uint64_t disk_reserved_kib;
+#if !defined(WIN32)
int pipe_master_wr;
+#else
+ void *pipe_master_wr_win;
+#endif
};
struct jpargs {
diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c
index f47cebe..75d35a7 100644
--- a/src/builder/b-sai.c
+++ b/src/builder/b-sai.c
@@ -957,13 +957,6 @@ int main(int argc, const char **argv)
if ((p = lws_cmdline_option(argc, argv, "-d")))
logs = atoi(p);
- if ((p = lws_cmdline_option(argc, argv, "--home")))
- /*
- * This is the deletion worker process being spawned, it only
- * needs to know the home dir to clean up inside
- */
- return sai_deletion_worker(p);
-
if ((p = lws_cmdline_option(argc, argv, "-c")))
config_dir = p;
@@ -1012,9 +1005,6 @@ int main(int argc, const char **argv)
return 1;
}
-// lwsl_notice("%s: parsed %s %s %s\n", __func__, builder.metrics_path,
-// builder.metrics_uri, builder.metrics_secret);
-
/*
* We need to sample the true uid / gid we should use inside
* the mountpoint for sai:nobody or sai:sai, by looking at
@@ -1063,7 +1053,47 @@ int main(int argc, const char **argv)
builder.pipe_master_wr = pfd[1];
}
#else
- /* TODO: windows worker process spawn */
+ {
+ char cmdline[512];
+ HANDLE hChildStd_IN_Rd = NULL;
+ HANDLE hChildStd_IN_Wr = NULL;
+ SECURITY_ATTRIBUTES sa;
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si;
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &sa, 0)) {
+ lwsl_err("CreatePipe failed\n");
+ return 1;
+ }
+ if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) {
+ lwsl_err("SetHandleInformation failed\n");
+ return 1;
+ }
+
+ memset(&pi, 0, sizeof(pi));
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = hChildStd_IN_Rd;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
+ lws_snprintf(cmdline, sizeof(cmdline), "%s --delete-worker --home=%s",
+ argv[0], builder.home);
+
+ if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0,
+ NULL, NULL, &si, &pi)) {
+ lwsl_err("CreateProcess failed\n");
+ return 1;
+ }
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ CloseHandle(hChildStd_IN_Rd);
+ builder.pipe_master_wr_win = hChildStd_IN_Wr;
+ }
#endif
#if defined(__linux__)
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index a75e216..d31f23b 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -403,10 +403,20 @@ saib_task_destroy(struct sai_nspawn *ns)
lwsl_notice("%s: task %s succeeded, requesting deletion of job dir %s\n",
__func__, ns->task->uuid, ns->inp);
+#if !defined(WIN32)
if (write(builder.pipe_master_wr, ns->task->uuid,
LWS_POSIX_LENGTH_CAST(strlen(ns->task->uuid))) != (ssize_t)strlen(ns->task->uuid))
lwsl_err("%s: failed to write to deletion worker\n",
__func__);
+#else
+ {
+ DWORD written;
+ if (!WriteFile(builder.pipe_master_wr_win, ns->task->uuid,
+ strlen(ns->task->uuid), &written, NULL))
+ lwsl_err("%s: failed to write to deletion worker\n",
+ __func__);
+ }
+#endif
}
if (ns->task) {
diff --git a/src/common/include/private.h b/src/common/include/private.h
index 1b59f23..76d1c40 100644
--- a/src/common/include/private.h
+++ b/src/common/include/private.h
@@ -209,7 +209,7 @@ struct sai_nspawn {
uint8_t finished_when_logs_drained:1;
uint8_t state_changed:1;
uint8_t user_cancel:1;
-
+ uint8_t reap_cb_called:1;
};
/*
diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c
index 0cd8436..1448ab2 100644
--- a/src/web/w-ws-browser.c
+++ b/src/web/w-ws-browser.c
@@ -1046,8 +1046,8 @@ enum_tasks:
t->art_up_nonce[0] = '\0';
t->art_down_nonce[0] = '\0';
- t->rebuildable = t->state == SAIES_FAIL &&
- (lws_now_secs() - (t->started + (t->duration / 1000000)) < 24 * 3600);
+ t->rebuildable = (t->state == SAIES_FAIL || t->state == SAIES_CANCELLED) &&
+ (lws_now_secs() - (t->started + t->duration / 1000000) < 24 * 3600);
/* only one in it at a time */
t = lws_container_of(task_owner.head, sai_task_t, list);
@@ -1210,7 +1210,8 @@ b_finish:
task_reply.event = sch->one_event;
task_reply.task = sch->one_task;
- sch->one_task->rebuildable = sch->one_task->state == SAIES_FAIL &&
+ sch->one_task->rebuildable = (sch->one_task->state == SAIES_FAIL ||
+ sch->one_task->state == SAIES_CANCELLED) &&
(lws_now_secs() - (sch->one_task->started +
(sch->one_task->duration / 1000000)) < 24 * 3600);
task_reply.auth_secs = (int)(pss->authorized ? pss->expiry_unix_time - lws_now_secs() : 0);