diff --git a/src/builder/b-comms.c b/src/builder/b-comms.c
index cb71a99..cbd0442 100644
--- a/src/builder/b-comms.c
+++ b/src/builder/b-comms.c
@@ -25,16 +25,35 @@
#include "b-private.h"
-#include "../common/struct-metadata.c"
+extern struct lws_spawn_piped *lsp_suspender;
-const lws_struct_map_t lsm_viewerstate_members[] = {
- LSM_UNSIGNED(sai_viewer_state_t, viewers, "viewers"),
-};
+#include "../common/struct-metadata.c"
static const lws_struct_map_t lsm_schema_json_loadreport[] = {
LSM_SCHEMA (sai_load_report_t, NULL, lsm_load_report_members, "com.warmcat.sai.loadreport"),
};
+static const lws_struct_map_t lsm_viewerstate_members[] = {
+ LSM_UNSIGNED(sai_viewer_state_t, viewers, "viewers"),
+};
+
+const lws_struct_map_t lsm_schema_map_m_to_b[] = {
+ LSM_SCHEMA (sai_task_t, NULL, lsm_task, "com-warmcat-sai-ta"),
+ LSM_SCHEMA (sai_cancel_t, NULL, lsm_task_cancel, "com.warmcat.sai.taskcan"),
+ LSM_SCHEMA (sai_viewer_state_t, NULL, lsm_viewerstate_members,
+ "com.warmcat.sai.viewerstate"),
+ LSM_SCHEMA (sai_resource_t, NULL, lsm_resource, "com-warmcat-sai-resource"),
+ LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, "com.warmcat.sai.rebuild")
+};
+
+enum {
+ SAIB_RX_TASK_ALLOCATION,
+ SAIB_RX_TASK_CANCEL,
+ SAIB_RX_VIEWERSTATE,
+ SAIB_RX_RESOURCE_REPLY,
+ SAIB_RX_REBUILD
+};
+
/*
* This is the only path to send things from builder->server.
*
@@ -109,18 +128,163 @@ saib_srv_queue_json_fragments_helper(struct lws_ss_handle *h,
}
static lws_ss_state_return_t
-saib_m_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
+saib_m_rx(void *userobj, const uint8_t *in, size_t len, int flags)
{
struct sai_plat_server *spm = (struct sai_plat_server *)userobj;
- //struct sai_plat *sp = (struct sai_plat *)spm->sai_plat;
+ sai_plat_t *sp = NULL;
+ sai_resource_t *reso;
+ struct lejp_ctx ctx;
+ lws_struct_args_t a;
+ sai_cancel_t *can;
+ sai_rebuild_t *reb;
+ int m;
-// lwsl_info("%s: len %d, flags: %d\n", __func__, (int)len, flags);
-// lwsl_hexdump_info(buf, len);
+ /*
+ * use the schema name on the incoming JSON to decide what kind of
+ * structure to instantiate
+ */
- if (saib_ws_json_rx_builder(spm, buf, len))
- return 1;
+ memset(&a, 0, sizeof(a));
+ a.map_st[0] = lsm_schema_map_m_to_b;
+ a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_schema_map_m_to_b);
+ a.ac_block_size = 512;
- return 0;
+// lwsl_hexdump_warn(in, len);
+
+ lws_struct_json_init_parse(&ctx, NULL, &a);
+ m = lejp_parse(&ctx, (uint8_t *)in, (int)len);
+ if (m < 0) {
+ lwsl_hexdump_err(in, len);
+ lwsl_err("%s: builder rx JSON decode failed '%s'\n",
+ __func__, lejp_error_to_string(m));
+ return m;
+ }
+
+ if (!a.dest) {
+ lwsac_free(&a.ac);
+ return LWSSSSRET_OK;
+ }
+
+ switch (a.top_schema_index) {
+
+ case SAIB_RX_TASK_ALLOCATION:
+ if (saib_consider_allocating_task(spm, &a, in, len, flags))
+ break;
+
+ break;
+
+ case SAIB_RX_TASK_CANCEL:
+
+ can = (sai_cancel_t *)a.dest;
+
+ lwsl_notice("%s: received task cancel for %s\n", __func__, can->task_uuid);
+
+ lws_start_foreach_dll_safe(struct lws_dll2 *, mp, mp1,
+ builder.sai_plat_owner.head) {
+ struct sai_plat *sp = lws_container_of(mp, struct sai_plat,
+ sai_plat_list);
+
+ lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,
+ sp->nspawn_owner.head) {
+ struct sai_nspawn *ns = lws_container_of(p,
+ struct sai_nspawn, list);
+
+ if (ns->task &&
+ !strcmp(can->task_uuid, ns->task->uuid)) {
+ lwsl_notice("%s: trying to cancel %s\n",
+ __func__, can->task_uuid);
+
+ /*
+ * We're going to send a few signals
+ * at 500ms intervals
+ */
+ ns->user_cancel = 1;
+ ns->term_budget = 5;
+
+ lws_sul_schedule(ns->builder->context, 0,
+ &ns->sul_task_cancel,
+ saib_sul_task_cancel, 1);
+ }
+
+ } lws_end_foreach_dll_safe(p, p1);
+
+ } lws_end_foreach_dll_safe(mp, mp1);
+ break;
+
+ case SAIB_RX_VIEWERSTATE:
+ {
+ sai_viewer_state_t *vs = (sai_viewer_state_t *)a.dest;
+ char any_busy = 0;
+
+ lwsl_notice("Received viewer state update: %u viewers\n", vs->viewers);
+
+ spm->viewer_count = vs->viewers;
+
+ if (!vs->viewers) {
+ lwsl_notice("%s: VIEWERSTATE: no viewers -> no load reports\n", __func__);
+ lws_sul_cancel(&spm->sul_load_report);
+ break;
+ }
+
+ /* are there any busy instances */
+
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
+ builder.sai_plat_owner.head) {
+ sp = lws_container_of(d, sai_plat_t, sai_plat_list);
+
+ lws_start_foreach_dll(struct lws_dll2 *, d, sp->nspawn_owner.head) {
+ struct sai_nspawn *ns = lws_container_of(d, struct sai_nspawn, list);
+
+ if (ns->state == NSSTATE_EXECUTING_STEPS)
+ any_busy = 1;
+
+ } lws_end_foreach_dll(d);
+ } lws_end_foreach_dll_safe(d, d1);
+
+ if (!any_busy) {
+ lwsl_notice("%s: VIEWERSTATE: no busy instances -> no load reports\n", __func__);
+
+ lws_sul_cancel(&spm->sul_load_report);
+ break;
+ }
+
+ /* At least one viewer, start reporting */
+ lwsl_notice("%s: VIEWERSTATE: viewers + busy instances -> load reports\n", __func__);
+
+ lws_sul_schedule(builder.context, 0, &spm->sul_load_report,
+ saib_sul_load_report_cb, 1);
+ }
+ break;
+
+ case SAIB_RX_RESOURCE_REPLY:
+ reso = (sai_resource_t *)a.dest;
+
+ lwsl_notice("%s: RESOURCE_REPLY: cookie %s\n",
+ __func__, reso->cookie);
+
+ saib_handle_resource_result(spm, (const char *)in, len);
+ break;
+
+ case SAIB_RX_REBUILD:
+ reb = (sai_rebuild_t *)a.dest;
+
+ lwsl_notice("%s: REBUILD: %s\n", __func__, reb->builder_name);
+
+ if (suspender_exists) {
+ uint8_t b = 3;
+ int fd = saib_suspender_get_pipe();
+
+ if (write(fd, &b, 1) != 1)
+ lwsl_err("%s: Failed to write to suspender\n",
+ __func__);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return LWSSSSRET_OK;
}
/*
diff --git a/src/builder/b-power.c b/src/builder/b-power.c
index 2193de2..185edd0 100644
--- a/src/builder/b-power.c
+++ b/src/builder/b-power.c
@@ -26,31 +26,6 @@
#include <stdlib.h>
#include <sys/types.h>
-#if !defined(WIN32)
-#include <pwd.h>
-#include <grp.h>
-#endif
-
-#if defined(__linux__) || defined(__APPLE__)
-#include <unistd.h>
-#endif
-
-#if defined(__APPLE__)
-#include <sys/stat.h> /* for mkdir() */
-#endif
-
-#if defined(WIN32)
-#include <initguid.h>
-#include <KnownFolders.h>
-#include <Shlobj.h>
-#include <processthreadsapi.h>
-#include <handleapi.h>
-
-
-#if !defined(PATH_MAX)
-#define PATH_MAX MAX_PATH
-#endif
-#endif
#include "b-private.h"
@@ -165,7 +140,7 @@ saib_stay_init(void)
if (!builder.url_sai_power)
return 1;
- if (!lsp_suspender)
+ if (!suspender_exists)
return LWSSSSRET_OK;
snprintf(builder.path, sizeof(builder.path) - 1, "%s/stay/%s",
@@ -196,15 +171,9 @@ static lws_ss_state_return_t
saib_power_link_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
{
#if !defined(WIN32)
+ int fd = saib_suspender_get_pipe();
uint8_t te = 0;
ssize_t n;
-#if defined(__linux__)
- int fd = lws_spawn_get_fd_stdxxx(lsp_suspender, 0);
-#endif
-#if defined(__APPLE__)
- int fd = builder.pipe_suspender_wr;
-#endif
-
if (len < 4 || !(flags & LWSSS_FLAG_SOM))
return 0;
@@ -215,7 +184,7 @@ saib_power_link_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
return LWSSSSRET_OK;
}
- if (!lsp_suspender)
+ if (!suspender_exists)
return LWSSSSRET_OK;
lwsl_notice("%s: sai-power scheduling power-off: doing shutdown...\n", __func__);
@@ -241,14 +210,9 @@ static void
sul_do_suspend_cb(lws_sorted_usec_list_t *sul)
{
#if !defined(WIN32)
+ int fd = saib_suspender_get_pipe();
uint8_t te = 1;
ssize_t n;
-#if defined(__linux__)
- int fd = lws_spawn_get_fd_stdxxx(lsp_suspender, 0);
-#endif
-#if defined(__APPLE__)
- int fd = builder.pipe_suspender_wr;
-#endif
lwsl_notice("%s: actioning suspend...\n", __func__);
diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index dec7b4e..6238489 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -1,7 +1,7 @@
/*
* Sai builder definitions src/builder/b-private.h
*
- * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2019 - 2025 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,32 @@
#include "../common/include/private.h"
+#if !defined(WIN32)
+#include <pwd.h>
+#include <grp.h>
+#endif
+
+#if defined(__linux__) || defined(__APPLE__)
+#include <unistd.h>
+#endif
+
+#if defined(__APPLE__)
+#include <sys/stat.h> /* for mkdir() */
+#endif
+
+#if defined(WIN32)
+#include <initguid.h>
+#include <KnownFolders.h>
+#include <Shlobj.h>
+#include <processthreadsapi.h>
+#include <handleapi.h>
+
+
+#if !defined(PATH_MAX)
+#define PATH_MAX MAX_PATH
+#endif
+#endif
+
#include <sys/stat.h>
#if defined(WIN32)
#include <direct.h>
@@ -37,6 +63,8 @@
#endif
#include <pthread.h>
+extern char suspender_exists;
+
struct lws_spawn_piped;
struct saib_opaque_spawn {
@@ -278,6 +306,15 @@ int
saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm,
const char *rej_task_uuid, unsigned int reason);
+int
+saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
+ const uint8_t *in, size_t len, int flags);
+
+void
+saib_sul_task_cancel(struct lws_sorted_usec_list *sul);
+
+int
+saib_suspender_get_pipe(void);
extern int
saib_suspender_fork(const char *path);
diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c
index bb08103..5f68b9e 100644
--- a/src/builder/b-sai.c
+++ b/src/builder/b-sai.c
@@ -95,7 +95,6 @@ static lws_state_notify_link_t nl;
struct sai_builder builder;
-extern struct lws_spawn_piped *lsp_suspender;
extern struct lws_protocols protocol_stdxxx;
extern struct lws_protocols protocol_suspender_stdxxx;
diff --git a/src/builder/b-suspender.c b/src/builder/b-suspender.c
index 16375c7..bca3f30 100644
--- a/src/builder/b-suspender.c
+++ b/src/builder/b-suspender.c
@@ -56,6 +56,19 @@
struct lws_spawn_piped *lsp_suspender;
struct lws_protocols protocol_suspender_stdxxx;
+char suspender_exists;
+
+int
+saib_suspender_get_pipe(void)
+{
+#if defined(__linux__)
+ int fd = lws_spawn_get_fd_stdxxx(lsp_suspender, 0);
+#endif
+#if defined(__APPLE__)
+ int fd = builder.pipe_suspender_wr;
+#endif
+ return fd;
+}
void *
saib_thread_suspend(void *d)
@@ -119,11 +132,11 @@ static void reap(void *opaque, const lws_spawn_resource_us_t *res,
int
saib_suspender_fork(const char *path)
{
+ char rpath[PATH_MAX];
#if defined(__linux__)
struct lws_spawn_piped_info info;
const char * const ea[] = { rpath, "-s", NULL };
#endif
- char rpath[PATH_MAX];
if (!realpath(path, rpath)) {
lwsl_err("%s: failed to get realpath for %s: %s\n", __func__,
@@ -189,6 +202,8 @@ saib_suspender_fork(const char *path)
}
#endif
+ suspender_exists = 1;
+
/*
* We start off idle, with no tasks on any platform and doing
* the grace time before suspend. If tasks appear, the grace
@@ -292,7 +307,7 @@ saib_suspender_start(void)
if (ret == 0) {
lws_snprintf(cmd, sizeof(cmd),
"PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin %s",
- builder.rebuild_script_root);
+ builder.rebuild_script_root);
system(cmd);
}
}
@@ -311,13 +326,8 @@ saib_suspender_start(void)
void
suspender_destroy()
{
-#if defined(__linux__)
- int fd = lws_spawn_get_fd_stdxxx(lsp_suspender, 0);
-#endif
-#if defined(__APPLE__)
- int fd = builder.pipe_suspender_wr;
-#endif
- if (lsp_suspender) {
+ if (suspender_exists) {
+ int fd = saib_suspender_get_pipe();
uint8_t te = 2;
/*
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index ced00e9..dff6a75 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -1,7 +1,7 @@
/*
* sai-builder task acquisition
*
- * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2019 - 2025 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -211,76 +211,39 @@ static char csep = '/';
static char csep = '\\';
#endif
-static const lws_struct_map_t lsm_viewerstate_members[] = {
- LSM_UNSIGNED(sai_viewer_state_t, viewers, "viewers"),
-};
-
-const lws_struct_map_t lsm_schema_map_m_to_b[] = {
- LSM_SCHEMA (sai_task_t, NULL, lsm_task, "com-warmcat-sai-ta"),
- LSM_SCHEMA (sai_cancel_t, NULL, lsm_task_cancel, "com.warmcat.sai.taskcan"),
- LSM_SCHEMA (sai_viewer_state_t, NULL, lsm_viewerstate_members,
- "com.warmcat.sai.viewerstate"),
- LSM_SCHEMA (sai_resource_t, NULL, lsm_resource, "com-warmcat-sai-resource"),
- LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, "com.warmcat.sai.rebuild")
-};
-
-enum {
- SAIB_RX_TASK_ALLOCATION,
- SAIB_RX_TASK_CANCEL,
- SAIB_RX_VIEWERSTATE,
- SAIB_RX_RESOURCE_REPLY,
- SAIB_RX_REBUILD
-};
-
-#if 0
-static const char * const nsstates[] = {
- "NSSTATE_INIT",
- "NSSTATE_MOUNTING",
- "NSSTATE_EXECUTING_STEPS",
- "NSSTATE_DONE",
- "NSSTATE_UPLOADING_ARTIFACTS",
- "NSSTATE_FAILED",
-};
-#endif
-
static void saib_start_artifact_upload(struct sai_nspawn *ns);
+
int
saib_set_ns_state(struct sai_nspawn *ns, int state)
{
-// char log[100];
-// int n;
-
- ns->state = (uint8_t)state;
- ns->state_changed = 1;
+ ns->state = (uint8_t)state;
+ ns->state_changed = 1;
-// if (state >= 0 && state < (int)LWS_ARRAY_SIZE(nsstates))
-// n = lws_snprintf(log, sizeof(log), ">saib> %s\n", nsstates[state]);
-// else
-// n = lws_snprintf(log, sizeof(log), ">saib> ILLEGAL_STATE %d\n", (int)state);
-
-// lwsl_user("%s: task %s: %s\n", __func__, ns->task ? ns->task->uuid : "null", log);
-
-// saib_log_chunk_create(ns, log, (unsigned int)n, 3);
-
- if (state == NSSTATE_EXECUTING_STEPS && ns->spm &&
- !ns->spm->sul_load_report.list.owner)
+ switch (state) {
+ case NSSTATE_EXECUTING_STEPS:
+ if (ns->spm && !ns->spm->sul_load_report.list.owner)
lws_sul_schedule(ns->builder->context, 0,
&ns->spm->sul_load_report,
saib_sul_load_report_cb, 1);
+ break;
- if (state == NSSTATE_UPLOADING_ARTIFACTS)
+ case NSSTATE_UPLOADING_ARTIFACTS:
saib_start_artifact_upload(ns);
+ break;
- if (state == NSSTATE_FAILED) {
+ case NSSTATE_FAILED:
ns->retcode = SAISPRF_EXIT | 254;
saib_task_grace(ns);
+ break;
+ default:
+ break;
}
- if (ns->spm && ns->spm->ss)
- return lws_ss_request_tx(ns->spm->ss) ? -1 : 0;
+ if (!ns->spm || !ns->spm->ss)
+ return 0;
- return 0;
+ return lws_ss_request_tx(ns->spm->ss) ? -1 : 0;
}
/*
@@ -289,7 +252,7 @@ saib_set_ns_state(struct sai_nspawn *ns, int state)
int
saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm,
- const char *rej_task_uuid, unsigned int reason)
+ const char *rej_task_uuid, unsigned int reason)
{
struct sai_rejection rej;
@@ -330,7 +293,8 @@ saib_task_destroy(struct sai_nspawn *ns)
{
int n;
- lwsl_notice("%s: destroying task %s\n", __func__, ns->task ? ns->task->uuid : "null");
+ lwsl_notice("%s: destroying task %s\n", __func__,
+ ns->task ? ns->task->uuid : "null");
lws_sul_cancel(&ns->sul_cleaner);
lws_sul_cancel(&ns->sul_task_cancel);
@@ -677,10 +641,11 @@ scan:
lws_sul_schedule(builder.context, 0, &ns->sul_cleaner,
saib_sub_cleaner_cb, 1);
} else
- lwsl_notice("%s: created / waiting on %d artifact uploads\n", __func__, ns->count_artifacts);
+ lwsl_notice("%s: created / waiting on %d artifact uploads\n",
+ __func__, ns->count_artifacts);
}
-static void
+void
saib_sul_task_cancel(struct lws_sorted_usec_list *sul)
{
struct sai_nspawn *ns = lws_container_of(sul,
@@ -702,519 +667,391 @@ saib_sul_task_cancel(struct lws_sorted_usec_list *sul)
saib_sul_task_cancel, 500 * LWS_US_PER_MS);
}
-extern struct lws_spawn_piped *lsp_suspender;
-
int
-saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len)
+saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
+ const uint8_t *in, size_t len, int flags)
{
+ char *p, mb[96], pur[128], ordinal_acc[SAI_BUILDER_INSTANCE_LIMIT],
+ script_path[512];
sai_plat_t *sp = NULL;
struct sai_nspawn *ns;
- sai_resource_t *reso;
- struct lejp_ctx ctx;
- lws_struct_args_t a;
- sai_cancel_t *can;
- sai_rebuild_t *reb;
+ int n, en, ml, fd;
+
sai_task_t *task;
- int n, m, en;
- char mb[96];
- char *p;
- int ml;
+
+ task = (sai_task_t *)a->dest;
+ task->ac_task_container = a->ac; /* bequeath lwsac responsibility */
/*
- * use the schema name on the incoming JSON to decide what kind of
- * structure to instantiate
+ * Server is requesting that a platform adopt a task...
+ *
+ * Multiple platforms may be using this connection to a given
+ * server so we have to disambiguate which platform he's
+ * tasking first.
*/
- memset(&a, 0, sizeof(a));
- a.map_st[0] = lsm_schema_map_m_to_b;
- a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_schema_map_m_to_b);
- a.ac_block_size = 512;
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
+ builder.sai_plat_owner.head) {
+ sp = lws_container_of(d, sai_plat_t, sai_plat_list);
-// lwsl_hexdump_warn(in, len);
+ if (!strcmp(sp->platform, task->platform))
+ break;
+ sp = NULL;
+ } lws_end_foreach_dll_safe(d, d1);
- lws_struct_json_init_parse(&ctx, NULL, &a);
- m = lejp_parse(&ctx, (uint8_t *)in, (int)len);
- if (m < 0) {
- lwsl_hexdump_err(in, len);
- lwsl_err("%s: builder rx JSON decode failed '%s'\n",
- __func__, lejp_error_to_string(m));
- return m;
- }
+ if (!sp) {
+ lwsl_err("%s: can't identify req task plat '%s'\n",
+ __func__, task->platform);
- if (!a.dest) {
- lwsac_free(&a.ac);
return 1;
}
- switch (a.top_schema_index) {
+ /*
+ * For debugging, it's good to see what tasks are ongoing
+ */
- case SAIB_RX_TASK_ALLOCATION:
- task = (sai_task_t *)a.dest;
- task->ac_task_container = a.ac; /* bequeath lwsac responsibility */
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
+ struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
- /*
- * Server is requesting that a platform adopt a task...
- *
- * Multiple platforms may be using this connection to a given
- * server so we have to disambiguate which platform he's
- * tasking first.
- */
+ lwsl_notice("%s: nspawn_census: %s\n", __func__, xns->task->uuid);
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
- builder.sai_plat_owner.head) {
- sp = lws_container_of(d, sai_plat_t, sai_plat_list);
+ } lws_end_foreach_dll_safe(d, d1);
- if (!strcmp(sp->platform, task->platform))
- break;
- sp = NULL;
- } lws_end_foreach_dll_safe(d, d1);
-
- if (!sp) {
- lwsl_err("%s: can't identify req task plat '%s'\n",
- __func__, task->platform);
+ /*
+ * store a copy of the toplevel ac used for the deserialization
+ * into the outer part of the c builder wrapper
+ */
- return 1;
- }
+ sp->deserialization_ac = a->ac;
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
- struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
+ /*
+ * Are we willing to take this task step on?
+ *
+ * We may connect to multiple servers and it's asynchronous
+ * which server may have tasked us first, so it's not that
+ * unusual to reject a task the server thought we could have
+ * taken
+ */
- lwsl_notice("%s: nspawn_census: %s\n", __func__, xns->task->uuid);
+ n = 0;
+ ns = NULL;
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
+ struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
- } lws_end_foreach_dll_safe(d, d1);
+ if (xns->task && !strcmp(xns->task->uuid, task->uuid)) {
+ lwsl_warn("%s: server offered task that's already running\n", __func__);
+ saib_queue_task_status_update(sp, spm, task->uuid,
+ SAI_TASK_REASON_DUPE);
+ return 0;
+ }
+ /* trying to reuse an nspawn? let's not do that... */
- /*
- * store a copy of the toplevel ac used for the deserialization
- * into the outer part of the c builder wrapper
- */
+ // if (!xns->task && !ns)
+ // ns = xns;
- sp->deserialization_ac = a.ac;
+ } lws_end_foreach_dll_safe(d, d1);
- /*
- * Are we willing to take this task step on?
- *
- * We may connect to multiple servers and it's asynchronous
- * which server may have tasked us first, so it's not that
- * unusual to reject a task the server thought we could have
- * taken
- */
+ /*
+ * We're not already running it, let's consider accepting it
+ */
- n = 0;
- ns = NULL;
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
- struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
- if (xns->task && !strcmp(xns->task->uuid, task->uuid)) {
- lwsl_warn("%s: server offered task that's already running\n", __func__);
- saib_queue_task_status_update(sp, spm, task->uuid, SAI_TASK_REASON_DUPE);
- return 0;
- }
- if (!xns->task && !ns)
- ns = xns;
- } lws_end_foreach_dll_safe(d, d1);
+ if (saib_can_accept_task(task, sp)) {
+ lwsl_warn("%s: builder rejects offered task\n", __func__);
+ if (saib_queue_task_status_update(sp, spm, task->uuid,
+ SAI_TASK_REASON_BUSY))
+ return -1;
+ return 0;
+ }
- if (saib_can_accept_task(task, sp)) {
- lwsl_warn("%s: builder rejects offered task\n", __func__);
- if (saib_queue_task_status_update(sp, spm, task->uuid, SAI_TASK_REASON_BUSY))
- return -1;
- return 0;
- }
+ /*
+ * We're going to accept the task. Create the nspawn.
+ */
- if (!ns) {
- char pur[128], *p, ordinal_acc[SAI_BUILDER_INSTANCE_LIMIT];
- int n;
+ ns = malloc(sizeof(*ns));
+ if (!ns)
+ return -1;
- ns = malloc(sizeof(*ns));
- if (!ns)
- return -1;
- memset(ns, 0, sizeof(*ns));
- ns->builder = &builder;
- ns->sp = sp;
-
- /*
- * Find the lowest free ordinal and use that. It doesn't
- * have any meaning for us, but the project being built needs
- * it in SAI_INSTANCE_IDX so ctest can use, eg, test ports
- * that don't conflict with any other running instance.
- */
-
- memset(ordinal_acc, 0, sizeof(ordinal_acc));
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
- struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
- assert(xns->instance_ordinal < (int)sizeof(ordinal_acc));
- ordinal_acc[xns->instance_ordinal] = 1;
- } lws_end_foreach_dll_safe(d, d1);
-
- for (n = 0; n < (int)sizeof(ordinal_acc); n++)
- if (ordinal_acc[n] == 0) {
- ns->instance_ordinal = n;
- break;
- }
+ memset(ns, 0, sizeof(*ns));
+ ns->builder = &builder;
+ ns->sp = sp;
+ /*
+ * Find the lowest free ordinal and use that. It doesn't
+ * have any meaning for us, but the project being built needs
+ * it in SAI_INSTANCE_IDX so ctest can use, eg, test ports
+ * that don't conflict with any other running instance.
+ */
- lws_dll2_add_tail(&ns->list, &sp->nspawn_owner);
+ memset(ordinal_acc, 0, sizeof(ordinal_acc));
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, sp->nspawn_owner.head) {
+ struct sai_nspawn *xns = lws_container_of(d, struct sai_nspawn, list);
- if (strstr(task->script, "sai-device")) {
- lws_strncpy(pur, sp->name, sizeof(pur));
- lws_filename_purify_inplace(pur);
- p = pur;
- while ((p = strchr(p, '/')))
- *p = '_';
+ assert(xns->instance_ordinal < (int)sizeof(ordinal_acc));
+ ordinal_acc[xns->instance_ordinal] = 1;
+ } lws_end_foreach_dll_safe(d, d1);
- lws_snprintf(ns->slp_control.sockpath,
- sizeof(ns->slp_control.sockpath),
-#if defined(__linux__)
- UDS_PATHNAME_LOGPROXY".%s.saib",
-#else
- UDS_PATHNAME_LOGPROXY"/%s.saib",
-#endif
- task->uuid);
- ns->slp_control.ns = ns;
- ns->slp_control.log_channel_idx = 3;
- if (saib_create_listen_uds(builder.context, &ns->slp_control,
- &ns->vhosts[0])) {
- lwsl_err("%s: Failed to create ctl log proxy listen UDS %s\n",
- __func__, ns->slp_control.sockpath);
- return -1;
- }
-
- for (n = 0; n < (int)LWS_ARRAY_SIZE(ns->slp); n++) {
- lws_snprintf(ns->slp[n].sockpath,
- sizeof(ns->slp[n].sockpath),
-#if defined(__linux__)
- UDS_PATHNAME_LOGPROXY".%s.tty%d",
-#else
- UDS_PATHNAME_LOGPROXY"/%s.tty%d",
-#endif
- task->uuid, n);
-
- ns->slp[n].ns = ns;
- ns->slp[n].log_channel_idx = n + 4;
-
- if (saib_create_listen_uds(builder.context, &ns->slp[n],
- &ns->vhosts[n + 1])) {
- lwsl_err("%s: Failed to create log proxy listen UDS %s\n",
- __func__, ns->slp[n].sockpath);
- return -1;
- }
- }
- }
+ for (n = 0; n < (int)sizeof(ordinal_acc); n++)
+ if (ordinal_acc[n] == 0) {
+ ns->instance_ordinal = n;
+ break;
}
-// lwsl_hexdump_warn(task->build, strlen(task->build));
+ lws_dll2_add_tail(&ns->list, &sp->nspawn_owner);
+
+ /*
+ * If we're using sai-device, sort out the log proxy
+ * information
+ */
- lws_strncpy(ns->fsm.distro, task->platform,
- sizeof(ns->fsm.distro));
- lws_filename_purify_inplace(ns->fsm.distro);
- p = ns->fsm.distro;
+ if (strstr(task->script, "sai-device")) {
+ lws_strncpy(pur, sp->name, sizeof(pur));
+ lws_filename_purify_inplace(pur);
+ p = pur;
while ((p = strchr(p, '/')))
*p = '_';
- /*
- * unique for remote server name ("warmcat"),
- * project name ("libwebsockets")
- */
- ns->server_name = spm->name;
- ns->project_name = task->repo_name;
- if (!strncmp(task->git_ref, "refs/heads/", 11))
- ns->ref = task->git_ref + 11;
- else
- if (!strncmp(task->git_ref, "refs/tags/", 10))
- ns->ref = task->git_ref + 10;
- else
- ns->ref = task->git_ref;
- ns->hash = task->git_hash;
- ns->git_repo_url = task->git_repo_url;
- if (ns->task && ns->task->ac_task_container)
- lwsac_free(&ns->task->ac_task_container);
-
- ns->task = task; /* we are owning this nspawn for the duration */
- ns->current_step = task->build_step;
- ns->build_step_count = task->build_step_count;
- if (!ns->current_step) {
- ns->spins = 0;
- ns->user_cancel = 0;
- ns->us_cpu_user = 0;
- ns->us_cpu_sys = 0;
- ns->worst_mem = 0;
- ns->worst_stg = 0;
- }
- ns->spm = spm; /* bind this task to the spm the req came in on */
-
- if (!ns->current_step) {
- saib_log_chunk_create(ns, ">saib>\n", 7, 3);
- saib_log_chunk_create(ns, ">saib>\n", 7, 3);
- saib_log_chunk_create(ns, ">saib>\n", 7, 3);
-
- ml = lws_snprintf(mb, sizeof(mb),
- ">saib> Sai Builder Version: %s, lws: %s\n",
- BUILD_INFO, LWS_BUILD_HASH);
- saib_log_chunk_create(ns, mb, (unsigned int)ml, 3);
- }
-
- saib_log_chunk_create(ns, ">saib>\n", 7, 3);
- ml = lws_snprintf(mb, sizeof(mb),
- ">saib> Starting task step %d ===>\n",
- ns->current_step + 1);
-
- saib_log_chunk_create(ns, mb, (unsigned int)ml, 3);
-
- saib_set_ns_state(ns, NSSTATE_INIT);
-
+ lws_snprintf(ns->slp_control.sockpath,
+ sizeof(ns->slp_control.sockpath),
#if defined(__linux__)
- ns->fsm.layers[0] = "base";
- ns->fsm.layers[1] = "env";
+ UDS_PATHNAME_LOGPROXY".%s.saib",
+#else
+ UDS_PATHNAME_LOGPROXY"/%s.saib",
#endif
-
- lws_snprintf(ns->fsm.ovname, sizeof(ns->fsm.ovname), "%s", task->uuid);
-
-// lwsl_notice("%s: server %s\n", __func__, ns->server_name);
-// lwsl_notice("%s: project %s\n", __func__, ns->project_name);
-// lwsl_notice("%s: ref %s\n", __func__, ns->ref);
-// lwsl_notice("%s: hash %s\n", __func__, ns->hash);
-// lwsl_notice("%s: distro %s\n", __func__, ns->fsm.distro);
-// lwsl_notice("%s: ovname %s\n", __func__, ns->fsm.ovname);
-// lwsl_notice("%s: git_repo_url %s\n", __func__, ns->git_repo_url);
-// lwsl_notice("%s: mountpoint %s\n", __func__, ns->fsm.mp);
-
- n = lws_snprintf(ns->inp, sizeof(ns->inp), "%s%c",
- builder.home, csep);
-
- n += lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n, "jobs%c",
- csep);
- lws_filename_purify_inplace(ns->inp);
- if (mkdir(ns->inp, 0755) && errno != EEXIST) {
- en = errno;
- lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
- goto ebail;
- }
-
- memcpy(ns->inp_vn, ns->fsm.ovname, 4);
- memcpy(ns->inp_vn + 4, ns->fsm.ovname + strlen(ns->fsm.ovname) - 4, 4);
- ns->inp_vn[8] = '\0';
-
- n += lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n, "%s%c",
- ns->inp_vn, csep);
- lws_filename_purify_inplace(ns->inp);
- if (mkdir(ns->inp, 0755) && errno != EEXIST) {
- en = errno;
- lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
-
- goto ebail;
+ task->uuid);
+ ns->slp_control.ns = ns;
+ ns->slp_control.log_channel_idx = 3;
+ if (saib_create_listen_uds(builder.context, &ns->slp_control,
+ &ns->vhosts[0])) {
+ lwsl_err("%s: Failed to create ctl log proxy listen UDS %s\n",
+ __func__, ns->slp_control.sockpath);
+ return -1;
}
- /*
- * Create a pending upload dir to mv artifacts into while
- * we get on with the next job.
- */
- lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n, "../.sai-uploads");
- if (mkdir(ns->inp, 0755) && errno != EEXIST) {
- en = errno;
- lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
-
- goto ebail;
- }
- /*
- * Snip that last bit off so ns->inp is the fully qualified
- * builder instance base dir
- */
- ns->inp[n] = '\0';
-
- {
- char script_path[512];
- int fd;
-#if !defined(WIN32)
- /* create git_helper.sh */
- lws_snprintf(script_path, sizeof(script_path), "%s%cgit_helper.sh",
- ns->inp, csep);
- fd = open(script_path, O_CREAT | O_TRUNC | O_WRONLY, 0755);
- if (fd < 0) {
- lwsl_warn("%s: failed to open git script for write %s\n", __func__, script_path);
- goto bail;
- }
-
- if ((size_t)write(fd, git_helper_sh, strlen(git_helper_sh)) != strlen(git_helper_sh)) {
- lwsl_warn("%s: failed to write git script %s\n", __func__, script_path);
- close(fd);
- goto bail;
- }
- close(fd);
+ for (n = 0; n < (int)LWS_ARRAY_SIZE(ns->slp); n++) {
+ lws_snprintf(ns->slp[n].sockpath,
+ sizeof(ns->slp[n].sockpath),
+#if defined(__linux__)
+ UDS_PATHNAME_LOGPROXY".%s.tty%d",
#else
- /* create git_helper.bat */
- lws_snprintf(script_path, sizeof(script_path), "%s%cgit_helper.bat",
- ns->inp, csep);
- if (_sopen_s(&fd, script_path, _O_CREAT | _O_TRUNC | _O_WRONLY,
- _SH_DENYNO, _S_IWRITE))
- fd = -1;
- if (fd < 0) {
- lwsl_warn("%s: failed to open git script for write %s\n", __func__, script_path);
- goto bail;
- }
-
- if ((size_t)write(fd, git_helper_bat, (unsigned int)strlen(git_helper_bat)) != strlen(git_helper_bat)) {
- lwsl_warn("%s: failed to write git script %s\n", __func__, script_path);
- close(fd);
- goto bail;
- }
- close(fd);
+ UDS_PATHNAME_LOGPROXY"/%s.tty%d",
#endif
- }
+ task->uuid, n);
- saib_set_ns_state(ns, NSSTATE_EXECUTING_STEPS);
+ ns->slp[n].ns = ns;
+ ns->slp[n].log_channel_idx = n + 4;
- ns->user_cancel = 0;
- ns->spins = 0;
-
- if (saib_spawn_script(ns)) {
- lwsl_err("%s: saib_spawn_script failed\n", __func__);
- goto bail;
+ if (saib_create_listen_uds(builder.context, &ns->slp[n],
+ &ns->vhosts[n + 1])) {
+ lwsl_err("%s: Failed to create log proxy listen UDS %s\n",
+ __func__, ns->slp[n].sockpath);
+ return -1;
+ }
}
+ }
- /* we're busy, we're not in the mood for suspending */
+// lwsl_hexdump_warn(task->build, strlen(task->build));
- lws_sul_cancel(&ns->builder->sul_idle);
- /*
- * We accepted the task
- */
+ lws_strncpy(ns->fsm.distro, task->platform,
+ sizeof(ns->fsm.distro));
+ lws_filename_purify_inplace(ns->fsm.distro);
+ p = ns->fsm.distro;
+ while ((p = strchr(p, '/')))
+ *p = '_';
- if (saib_queue_task_status_update(sp, spm, task->uuid, SAI_TASK_REASON_ACCEPTED))
- goto bail;
+ /*
+ * unique for remote server name ("warmcat"),
+ * project name ("libwebsockets")
+ */
+ ns->server_name = spm->name;
+ ns->project_name = task->repo_name;
+ if (!strncmp(task->git_ref, "refs/heads/", 11))
+ ns->ref = task->git_ref + 11;
+ else
+ if (!strncmp(task->git_ref, "refs/tags/", 10))
+ ns->ref = task->git_ref + 10;
+ else
+ ns->ref = task->git_ref;
+ ns->hash = task->git_hash;
+ ns->git_repo_url = task->git_repo_url;
+ if (ns->task && ns->task->ac_task_container)
+ lwsac_free(&ns->task->ac_task_container);
-#if defined(__APPLE__)
+ ns->task = task; /* we are owning this nspawn for the duration */
+ ns->current_step = task->build_step;
+ ns->build_step_count = task->build_step_count;
+ if (!ns->current_step) {
+ ns->spins = 0;
+ ns->user_cancel = 0;
+ ns->us_cpu_user = 0;
+ ns->us_cpu_sys = 0;
+ ns->worst_mem = 0;
+ ns->worst_stg = 0;
+ }
+ ns->spm = spm; /* bind this task to the spm the req came in on */
+
+ if (!ns->current_step) {
/*
- * If we started the first task, acquire a wakelock to prevent
- * idle suspend
+ * If it's the first step, log some preamble info
*/
- if (sp->nspawn_owner.count == 1 && !builder.wakelock_pid) {
- pid_t pid = fork();
-
- if (pid == -1)
- lwsl_err("%s: fork for wakelock failed\n", __func__);
- else if (!pid) {
- execl("/usr/bin/caffeinate", "/usr/bin/caffeinate", "-i", (char *)NULL);
- exit(1); /* should not get here */
- } else {
- lwsl_notice("%s: acquired wakelock (pid %d)\n", __func__, (int)pid);
- builder.wakelock_pid = pid;
- }
- }
- /* if there's a pending wakelock release, cancel it */
- lws_sul_cancel(&builder.sul_release_wakelock);
-#endif
+ saib_log_chunk_create(ns, ">saib>\n", 7, 3);
+ saib_log_chunk_create(ns, ">saib>\n", 7, 3);
+ saib_log_chunk_create(ns, ">saib>\n", 7, 3);
- break;
+ ml = lws_snprintf(mb, sizeof(mb),
+ ">saib> Sai Builder Version: %s, lws: %s\n",
+ BUILD_INFO, LWS_BUILD_HASH);
+ saib_log_chunk_create(ns, mb, (unsigned int)ml, 3);
+ }
- case SAIB_RX_TASK_CANCEL:
+ saib_log_chunk_create(ns, ">saib>\n", 7, 3);
+ ml = lws_snprintf(mb, sizeof(mb),
+ ">saib> Starting task step %d ===>\n",
+ ns->current_step + 1);
- can = (sai_cancel_t *)a.dest;
+ saib_log_chunk_create(ns, mb, (unsigned int)ml, 3);
- lwsl_notice("%s: received task cancel for %s\n", __func__, can->task_uuid);
+ saib_set_ns_state(ns, NSSTATE_INIT);
- lws_start_foreach_dll_safe(struct lws_dll2 *, mp, mp1,
- builder.sai_plat_owner.head) {
- struct sai_plat *sp = lws_container_of(mp, struct sai_plat,
- sai_plat_list);
+#if defined(__linux__)
+ ns->fsm.layers[0] = "base";
+ ns->fsm.layers[1] = "env";
+#endif
- lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,
- sp->nspawn_owner.head) {
- struct sai_nspawn *ns = lws_container_of(p,
- struct sai_nspawn, list);
+ lws_snprintf(ns->fsm.ovname, sizeof(ns->fsm.ovname), "%s", task->uuid);
- if (ns->task &&
- !strcmp(can->task_uuid, ns->task->uuid)) {
- lwsl_notice("%s: trying to cancel %s\n",
- __func__, can->task_uuid);
+ n = lws_snprintf(ns->inp, sizeof(ns->inp), "%s%c",
+ builder.home, csep);
- /*
- * We're going to send a few signals
- * at 500ms intervals
- */
- ns->user_cancel = 1;
- ns->term_budget = 5;
- lws_sul_schedule(ns->builder->context, 0,
- &ns->sul_task_cancel,
- saib_sul_task_cancel, 1);
- }
+ n += lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n, "jobs%c",
+ csep);
+ lws_filename_purify_inplace(ns->inp);
- } lws_end_foreach_dll_safe(p, p1);
+ if (mkdir(ns->inp, 0755) && errno != EEXIST) {
+ en = errno;
+ lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
+ goto ebail;
+ }
- } lws_end_foreach_dll_safe(mp, mp1);
- break;
+ memcpy(ns->inp_vn, ns->fsm.ovname, 4);
+ memcpy(ns->inp_vn + 4, ns->fsm.ovname + strlen(ns->fsm.ovname) - 4, 4);
+ ns->inp_vn[8] = '\0';
- case SAIB_RX_VIEWERSTATE:
- {
- sai_viewer_state_t *vs = (sai_viewer_state_t *)a.dest;
- char any_busy = 0;
+ n += lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n, "%s%c",
+ ns->inp_vn, csep);
+ lws_filename_purify_inplace(ns->inp);
+ if (mkdir(ns->inp, 0755) && errno != EEXIST) {
+ en = errno;
+ lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
- lwsl_notice("Received viewer state update: %u viewers\n", vs->viewers);
+ goto ebail;
+ }
- spm->viewer_count = vs->viewers;
+ /*
+ * Create a pending upload dir to mv artifacts into while
+ * we get on with the next job.
+ */
+ lws_snprintf(ns->inp + n, sizeof(ns->inp) - (unsigned int)n,
+ "../.sai-uploads");
- if (!vs->viewers) {
- lwsl_notice("%s: VIEWERSTATE: no viewers -> no load reports\n", __func__);
- lws_sul_cancel(&spm->sul_load_report);
- break;
- }
+ if (mkdir(ns->inp, 0755) && errno != EEXIST) {
+ en = errno;
+ lwsl_err("%s: mkdir %s -> errno %d\n", __func__, ns->inp, en);
- /* are there any busy instances */
+ goto ebail;
+ }
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
- builder.sai_plat_owner.head) {
- sp = lws_container_of(d, sai_plat_t, sai_plat_list);
+ /*
+ * Snip that last bit off so ns->inp is the fully qualified
+ * builder instance base dir
+ */
- lws_start_foreach_dll(struct lws_dll2 *, d, sp->nspawn_owner.head) {
- struct sai_nspawn *ns = lws_container_of(d, struct sai_nspawn, list);
+ ns->inp[n] = '\0';
- if (ns->state == NSSTATE_EXECUTING_STEPS)
- any_busy = 1;
- } lws_end_foreach_dll(d);
- } lws_end_foreach_dll_safe(d, d1);
+#if !defined(WIN32)
+ /* create git_helper.sh */
+ lws_snprintf(script_path, sizeof(script_path), "%s%cgit_helper.sh",
+ ns->inp, csep);
+ fd = open(script_path, O_CREAT | O_TRUNC | O_WRONLY, 0755);
+ if (fd < 0) {
+ lwsl_warn("%s: failed to open git script for write %s\n",
+ __func__, script_path);
+ goto bail;
+ }
- if (!any_busy) {
- lwsl_notice("%s: VIEWERSTATE: no busy instances -> no load reports\n", __func__);
+ if ((size_t)write(fd, git_helper_sh, strlen(git_helper_sh)) != strlen(git_helper_sh)) {
+ lwsl_warn("%s: failed to write git script %s\n", __func__, script_path);
+ close(fd);
+ goto bail;
+ }
+ close(fd);
+#else
+ /* create git_helper.bat */
+ lws_snprintf(script_path, sizeof(script_path), "%s%cgit_helper.bat",
+ ns->inp, csep);
+ if (_sopen_s(&fd, script_path, _O_CREAT | _O_TRUNC | _O_WRONLY,
+ _SH_DENYNO, _S_IWRITE))
+ fd = -1;
+ if (fd < 0) {
+ lwsl_warn("%s: failed to open git script for write %s\n", __func__, script_path);
+ goto bail;
+ }
- lws_sul_cancel(&spm->sul_load_report);
- break;
- }
+ if ((size_t)write(fd, git_helper_bat, (unsigned int)strlen(git_helper_bat)) != strlen(git_helper_bat)) {
+ lwsl_warn("%s: failed to write git script %s\n", __func__, script_path);
+ close(fd);
+ goto bail;
+ }
+ close(fd);
+#endif
- /* At least one viewer, start reporting */
- lwsl_notice("%s: VIEWERSTATE: viewers + busy instances -> load reports\n", __func__);
+ saib_set_ns_state(ns, NSSTATE_EXECUTING_STEPS);
- lws_sul_schedule(builder.context, 0, &spm->sul_load_report,
- saib_sul_load_report_cb, 1);
- }
- break;
+ ns->user_cancel = 0;
+ ns->spins = 0;
- case SAIB_RX_RESOURCE_REPLY:
- reso = (sai_resource_t *)a.dest;
+ if (saib_spawn_script(ns)) {
+ lwsl_err("%s: saib_spawn_script failed\n", __func__);
+ goto bail;
+ }
- lwsl_notice("%s: RESOURCE_REPLY: cookie %s\n",
- __func__, reso->cookie);
+ /* we're busy, we're not in the mood for suspending */
- saib_handle_resource_result(spm, in, len);
- break;
+ lws_sul_cancel(&ns->builder->sul_idle);
- case SAIB_RX_REBUILD:
- reb = (sai_rebuild_t *)a.dest;
+ /*
+ * We accepted the task
+ */
- lwsl_notice("%s: REBUILD: %s\n", __func__, reb->builder_name);
+ if (saib_queue_task_status_update(sp, spm, task->uuid, SAI_TASK_REASON_ACCEPTED))
+ goto bail;
- if (lsp_suspender) {
- uint8_t b = 3;
- if (write(lws_spawn_get_fd_stdxxx(lsp_suspender, 0), &b, 1) != 1)
- lwsl_err("%s: Failed to write to suspender\n",
- __func__);
+#if defined(__APPLE__)
+ /*
+ * If we started the first task, acquire a wakelock to prevent
+ * idle suspend
+ */
+ if (sp->nspawn_owner.count == 1 && !builder.wakelock_pid) {
+ pid_t pid = fork();
+
+ if (pid == -1)
+ lwsl_err("%s: fork for wakelock failed\n", __func__);
+ else if (!pid) {
+ execl("/usr/bin/caffeinate", "/usr/bin/caffeinate", "-i", (char *)NULL);
+ exit(1); /* should not get here */
+ } else {
+ lwsl_notice("%s: acquired wakelock (pid %d)\n", __func__, (int)pid);
+ builder.wakelock_pid = pid;
}
- break;
-
- default:
- break;
}
+ /* if there's a pending wakelock release, cancel it */
+ lws_sul_cancel(&builder.sul_release_wakelock);
+#endif
return 0;