Keep FastCGI available during restarts

This commit is contained in:
udo 2026-07-16 22:00:08 +00:00
parent 93c701c6c7
commit caffb3f404
16 changed files with 192 additions and 41 deletions

View File

@ -145,6 +145,25 @@ module lives in the configured writable cache root rather than beside the
possibly root-owned deployed `core.wasm`; freshness still uses the deployed
artifact's metadata.
Packaged deployments use systemd socket activation for FastCGI. The socket unit
owns `/run/uce/fastcgi.sock`; UCE validates and adopts the single named listener
after exec. The listener therefore remains connectable and queues requests while
the service and its post-fork workers restart. Direct launches without systemd
activation retain the existing configured Unix/TCP listener behavior.
On termination the parent asks render workers to close their listeners, finish
accepted connections within the bounded worker drain interval, and only then
exits. This prevents an accepted FastCGI request from being reset at handoff;
the socket unit queues later connections for the replacement workers.
The graceful signal handler belongs to the parent and render workers. Generic
`task()` children restore default termination signals after fork so
`task_kill()` and `server_stop()` retain their immediate stop contract.
Epoch interruption measures uninterrupted guest CPU segments. The common
hostcall membrane re-arms the store deadline after every native call, excluding
blocking I/O, process waits, hashing, and other host work without weakening a
guest loop that makes no hostcalls. Keeping this at the membrane also covers new
hostcalls without per-import timeout bookkeeping.
`request_perf()` reports worker module-cache hits and misses and divides a miss
into artifact lookup, wasm read, custom-section parse, serialized-module
deserialization or wasm compilation, and immutable import classification. This

View File

@ -4,7 +4,8 @@ set -e
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload >/dev/null 2>&1 || true
if [ "$1" = "configure" ]; then
systemctl enable uce.service >/dev/null 2>&1 || true
systemctl enable uce.socket uce.service >/dev/null 2>&1 || true
systemctl start uce.socket >/dev/null 2>&1 || true
systemctl restart uce.service >/dev/null 2>&1 || true
fi
fi

View File

@ -3,7 +3,7 @@ set -e
if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ]; then
if command -v systemctl >/dev/null 2>&1; then
systemctl disable --now uce.service >/dev/null 2>&1 || true
systemctl disable --now uce.service uce.socket >/dev/null 2>&1 || true
fi
fi

View File

@ -1,7 +1,8 @@
[Unit]
Description=UCE FastCGI Runtime
After=network-online.target mariadb.service memcached.service
After=network-online.target mariadb.service memcached.service uce.socket
Wants=network-online.target
Requires=uce.socket
[Service]
Type=simple
@ -10,12 +11,10 @@ RuntimeDirectory=uce
StateDirectory=uce
CacheDirectory=uce
ExecStartPre=/usr/bin/mkdir -p /var/cache/uce/work /var/lib/uce/uploads /var/lib/uce/sessions
ExecStartPre=/usr/bin/rm -f /run/uce/fastcgi.sock
ExecStart=/usr/lib/uce/bin/uce_fastcgi.linux.bin
ExecStopPost=/usr/bin/rm -f /run/uce/fastcgi.sock
Restart=always
RestartSec=2
TimeoutStopSec=15
TimeoutStopSec=30
KillMode=mixed
StandardOutput=journal
StandardError=journal

15
scripts/deb/uce.socket Normal file
View File

@ -0,0 +1,15 @@
[Unit]
Description=UCE FastCGI socket
[Socket]
ListenStream=/run/uce/fastcgi.sock
FileDescriptorName=fastcgi
SocketUser=www-data
SocketGroup=www-data
SocketMode=0660
DirectoryMode=0755
Backlog=100
Service=uce.service
[Install]
WantedBy=sockets.target

View File

@ -205,6 +205,7 @@ bundle_wasmtime "$STAGE_DIR"
write_packaged_settings "$STAGE_DIR/etc/uce/settings.cfg" "$WEBROOT"
install -m 0644 "$DEB_ASSET_DIR/uce.service" "$STAGE_DIR/lib/systemd/system/uce.service"
install -m 0644 "$DEB_ASSET_DIR/uce.socket" "$STAGE_DIR/lib/systemd/system/uce.socket"
install -m 0644 "$DEB_ASSET_DIR/conffiles" "$DEBIAN_DIR/conffiles"
install -m 0755 "$DEB_ASSET_DIR/postinst" "$DEBIAN_DIR/postinst"
install -m 0755 "$DEB_ASSET_DIR/prerm" "$DEBIAN_DIR/prerm"

View File

@ -179,6 +179,7 @@ bundle_wasi_sdk "$STAGE_DIR"
bundle_wasmtime "$STAGE_DIR"
write_packaged_settings "$STAGE_DIR/etc/uce/settings.cfg" "$WEBROOT"
install -m 0644 "$REPO_ROOT/scripts/deb/uce.service" "$STAGE_DIR/usr/lib/systemd/system/uce.service"
install -m 0644 "$REPO_ROOT/scripts/deb/uce.socket" "$STAGE_DIR/usr/lib/systemd/system/uce.socket"
(
cd "$STAGE_DIR"
@ -225,13 +226,14 @@ cp -a %{_builddir}/$PACKAGE_NAME-$VERSION/. %{buildroot}/
%post
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload >/dev/null 2>&1 || true
systemctl enable uce.service >/dev/null 2>&1 || true
systemctl enable uce.socket uce.service >/dev/null 2>&1 || true
systemctl start uce.socket >/dev/null 2>&1 || true
systemctl restart uce.service >/dev/null 2>&1 || true
fi
%preun
if [ "\$1" = "0" ] && command -v systemctl >/dev/null 2>&1; then
systemctl disable --now uce.service >/dev/null 2>&1 || true
systemctl disable --now uce.service uce.socket >/dev/null 2>&1 || true
fi
%postun
@ -245,6 +247,7 @@ fi
%config(noreplace) /etc/uce/settings.cfg
/usr/lib/uce
/usr/lib/systemd/system/uce.service
/usr/lib/systemd/system/uce.socket
$WEBROOT
%dir /var/cache/uce
%dir /var/lib/uce

View File

@ -73,4 +73,5 @@ if [[ "$action" == "run" ]]; then
scripts/test_mysql_epoch_refresh.sh
scripts/test_mysql_persistent_pool.sh
scripts/test_log_timeliness.sh
scripts/test_socket_activation.sh
fi

View File

@ -1,7 +1,8 @@
[Unit]
Description=UCE FastCGI Runtime
After=network-online.target mariadb.service memcached.service
After=network-online.target mariadb.service memcached.service uce.socket
Wants=network-online.target
Requires=uce.socket
[Service]
Type=simple
@ -10,13 +11,11 @@ RuntimeDirectory=uce
StateDirectory=uce
CacheDirectory=uce
ExecStartPre=/usr/bin/mkdir -p /var/cache/uce/work /var/lib/uce/uploads /var/lib/uce/sessions
ExecStartPre=/usr/bin/rm -f /run/uce/fastcgi.sock
ExecStartPre=/usr/bin/bash /Code/uce.openfu.com/uce/scripts/build_linux.sh
ExecStart=/Code/uce.openfu.com/uce/bin/uce_fastcgi.linux.bin
ExecStopPost=/usr/bin/rm -f /run/uce/fastcgi.sock
Restart=always
RestartSec=2
TimeoutStopSec=15
TimeoutStopSec=30
KillMode=mixed
StandardOutput=journal
StandardError=journal

View File

@ -0,0 +1,15 @@
[Unit]
Description=UCE FastCGI socket
[Socket]
ListenStream=/run/uce/fastcgi.sock
FileDescriptorName=fastcgi
SocketUser=www-data
SocketGroup=www-data
SocketMode=0660
DirectoryMode=0755
Backlog=100
Service=uce.service
[Install]
WantedBy=sockets.target

View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
service_name="${UCE_TEST_SERVICE:-uce.service}"
socket_name="${UCE_TEST_SOCKET_SERVICE:-uce.socket}"
http_host="${UCE_TEST_HTTP_HOST:-uce.openfu.com}"
http_path="${UCE_TEST_HTTP_PATH:-/info/}"
requests="${UCE_TEST_RESTART_REQUESTS:-100}"
statuses=$(mktemp)
trap 'rm -f "$statuses"' EXIT
systemctl is-active --quiet "$socket_name"
systemctl is-active --quiet "$service_name"
socket_path=$(systemctl show -p Listen --value "$socket_name" | sed -n 's/ \+(Stream)$//p')
[[ -S "$socket_path" ]]
inode_before=$(stat -c %i "$socket_path")
(
for ((i = 0; i < requests; i++)); do
curl -sS --max-time 15 -o /dev/null -w '%{http_code}\n' \
-H "Host: $http_host" "http://127.0.0.1${http_path}"
done
) >"$statuses" &
load_pid=$!
sleep 0.05
systemctl restart "$service_name"
wait "$load_pid"
inode_after=$(stat -c %i "$socket_path")
[[ "$inode_after" = "$inode_before" ]]
[[ $(wc -l <"$statuses") -eq "$requests" ]]
if [[ $(grep -c '^200$' "$statuses") -ne "$requests" ]]; then
sort "$statuses" | uniq -c >&2
exit 1
fi
systemctl is-active --quiet "$socket_name"
systemctl is-active --quiet "$service_name"
echo "socket activation restart passed across $requests HTTP requests"

View File

@ -206,7 +206,6 @@ FastCGIServer::shutdown()
{
printf("Closing server socket %i\n", *it);
close(*it);
sleep(1);
}
for (std::vector<std::string>::iterator it = listen_unlink.begin();
@ -223,7 +222,6 @@ FastCGIServer::shutdown()
delete it->second;
}
sleep(1);
server_sockets.clear();
}
@ -264,6 +262,22 @@ FastCGIServer::listen(unsigned tcp_port)
return(listen(tcp_port, "0.0.0.0"));
}
int
FastCGIServer::adopt_listener(int socket_handle, char type)
{
int accepting = 0;
socklen_t accepting_size = sizeof(accepting);
if(socket_handle < 0 || getsockopt(socket_handle, SOL_SOCKET, SO_ACCEPTCONN,
&accepting, &accepting_size) != 0 || !accepting)
throw std::runtime_error("inherited descriptor is not a listening socket");
set_socket_nonblocking(socket_handle);
server_sockets.push_back(socket_handle);
server_socket_types[socket_handle] = type;
printf("(P) adopted #%i inherited %s listener\n", socket_handle,
type == 'F' ? "FastCGI" : "server");
return(socket_handle);
}
int
FastCGIServer::listen(unsigned tcp_port, const std::string& bind_address)
{

View File

@ -57,6 +57,7 @@ public:
int listen_http(unsigned tcp_port, const std::string& bind_address);
int listen_cli(const std::string& local_path);
int listen(const std::string& local_path);
int adopt_listener(int socket_handle, char type = 'F');
void process(int timeout_ms = -1); // timeout_ms<0 blocks forever
void process_forever();

View File

@ -1549,6 +1549,12 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
{
close_locked_file(lock_fd);
my_pid = getpid();
// The FastCGI worker handles termination to drain accepted requests.
// Generic task children do not run that drain loop, so inheriting those
// handlers would turn task_kill(SIGTERM) into a no-op.
signal(SIGTERM, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGALRM, SIG_DFL);
if(timeout > 0)
alarm(timeout);

View File

@ -699,15 +699,7 @@ volatile bool termination_signal_received = false;
void on_terminate(int sig)
{
if(termination_signal_received)
return;
termination_signal_received = true;
if(getpid() != parent_pid)
exit(1);
printf("Terminating... PID %i:%i\n", getpid(), parent_pid);
wasm_backend_shutdown();
server.shutdown();
exit(1);
}
void clear_shared_unit_cache(ServerState& state)
@ -1069,7 +1061,7 @@ void run_ws_broker()
ws_broker.listen(server_state.config["WS_BROKER_SOCKET_PATH"]);
chmod(server_state.config["WS_BROKER_SOCKET_PATH"].c_str(), S_IRWXU | S_IRGRP | S_IWGRP);
}
for(;;)
while(!termination_signal_received)
{
ws_broker.process(50);
ws_broker_drain_outbound(ws_broker_outbound_timeout_seconds);
@ -1254,7 +1246,7 @@ void run_proactive_compiler()
}
next_scan_at = time_precise();
for(;;)
while(!termination_signal_received)
{
try
{
@ -1397,10 +1389,21 @@ void listen_for_connections()
printf("(P) wasm worker ready: PID %i in %.3f ms\n", getpid(), wasm_ms);
else
fprintf(stderr, "(!) wasm worker initialization failed: PID %i in %.3f ms: %s\n", getpid(), wasm_ms, wasm_error.c_str());
for(;;)
while(!termination_signal_received)
{
server.process(-1);
}
close_inherited_server_sockets();
f64 drain_deadline = time_precise() + (f64)to_u64(server_state.config["WORKER_DRAIN_TIMEOUT_SECONDS"], 10);
while(!server.client_sockets.empty() && time_precise() < drain_deadline)
server.process(100);
if(!server.client_sockets.empty())
fprintf(stderr, "(!) worker PID %i drain deadline reached with %zu client connections\n",
getpid(), server.client_sockets.size());
else
printf("(P) worker PID %i drained cleanly\n", getpid());
wasm_backend_shutdown();
exit(server.client_sockets.empty() ? 0 : 1);
}
mode_t configured_socket_mode(String value, mode_t fallback)
@ -1424,6 +1427,25 @@ void chmod_configured_socket(String path, String mode_value, mode_t fallback)
fprintf(stderr, "(!) Could not chmod socket %s to %04o: %s\n", path.c_str(), (unsigned int)mode, strerror(errno));
}
int systemd_fastcgi_listener()
{
const char* listen_pid = getenv("LISTEN_PID");
const char* listen_fds = getenv("LISTEN_FDS");
if(!listen_pid || !listen_fds)
return(-1);
if(to_u64(listen_pid, 0) != (u64)getpid())
return(-1);
if(to_u64(listen_fds, 0) != 1)
throw std::runtime_error("UCE requires exactly one systemd FastCGI listener");
const char* names = getenv("LISTEN_FDNAMES");
if(names && names[0] != '\0' && String(names) != "fastcgi")
throw std::runtime_error("systemd listener must be named fastcgi");
unsetenv("LISTEN_PID");
unsetenv("LISTEN_FDS");
unsetenv("LISTEN_FDNAMES");
return(3);
}
StringMap redacted_server_config_for_log(const StringMap& config)
{
StringMap redacted = config;
@ -1443,13 +1465,16 @@ void init_base_process()
server_state.config = make_server_settings();
server_state.config["COMPILER_SYS_PATH"] = cwd_get();
printf("Compiler base path: %s\n", server_state.config["COMPILER_SYS_PATH"].c_str());
int inherited_fastcgi = systemd_fastcgi_listener();
if(inherited_fastcgi >= 0)
server.adopt_listener(inherited_fastcgi, 'F');
if(server_state.config["FCGI_PORT"] != "")
server.listen(int_val(server_state.config["FCGI_PORT"]));
printf("%s\n", var_dump(redacted_server_config_for_log(server_state.config)).c_str());
if(server_state.config["FCGI_SOCKET_PATH"] != "")
if(inherited_fastcgi < 0 && server_state.config["FCGI_SOCKET_PATH"] != "")
{
server.listen(server_state.config["FCGI_SOCKET_PATH"]);
chmod_configured_socket(server_state.config["FCGI_SOCKET_PATH"], server_state.config["FCGI_SOCKET_MODE"], 0666);
@ -1469,7 +1494,9 @@ void init_base_process()
mkdir(server_state.config["SESSION_PATH"]);
signal(SIGCHLD, on_child_exit);
signal(SIGTERM, on_terminate);
signal(SIGINT, on_terminate);
signal(SIGHUP, on_terminate);
signal(SIGPIPE, SIG_IGN);
srand(time());
}
@ -1489,7 +1516,7 @@ int main(int argc, char** argv)
ensure_proactive_compiler();
ensure_ws_broker();
for(;;)
while(!termination_signal_received)
{
if(!proactive_compiler_alive())
proactive_compiler_pid = 0;
@ -1512,5 +1539,22 @@ int main(int argc, char** argv)
sleep(1);
}
printf("(P) draining %zu workers before shutdown\n", workers.size());
for(auto& worker : workers)
kill(worker.first, SIGTERM);
if(proactive_compiler_pid > 0)
kill(proactive_compiler_pid, SIGTERM);
if(ws_broker_pid > 0)
kill(ws_broker_pid, SIGTERM);
f64 drain_deadline = time_precise() + (f64)to_u64(server_state.config["WORKER_DRAIN_TIMEOUT_SECONDS"], 10);
while(!workers.empty() && time_precise() < drain_deadline)
{
on_child_exit(0);
usleep(10000);
}
for(auto& worker : workers)
kill(worker.first, SIGKILL);
server.shutdown();
return 0;
}

View File

@ -2106,6 +2106,11 @@ private:
auto profiled = [self, callback, profile_name](Caller caller, Span<const Val> args, Span<Val> results) mutable -> Result<std::monostate, Trap> {
auto started = std::chrono::steady_clock::now();
auto result = callback(caller, args, results);
// Epoch interruption limits guest CPU, not time spent in native I/O,
// process management, hashing, or other host work. Re-arm at the one
// membrane every hostcall crosses so newly added blocking imports
// cannot silently consume the next guest segment's budget.
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
if(profile_name != "uce_host_request_perf")
{
u64 elapsed = (u64)std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - started).count();
@ -2288,9 +2293,9 @@ private:
if(mod == "env" && name == "uce_host_crypto_equal")
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String a,b; self->hostcall_read(args[0].i32(), args[1].i32(), a); self->hostcall_read(args[2].i32(), args[3].i32(), b); results[0]=Val((int32_t)(crypto_equal_native(a,b)?1:0)); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_password_hash")
return(add([self](Caller caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String password; self->hostcall_read(args[0].i32(), args[1].i32(), password); String out=password_hash_native(password); u32 cap=(u32)args[3].i32(); int32_t buf=args[2].i32(); if(buf&&cap>=out.size()) self->hostcall_write(buf,out); caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks); results[0]=Val((int32_t)out.size()); return(std::monostate()); }));
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String password; self->hostcall_read(args[0].i32(), args[1].i32(), password); String out=password_hash_native(password); u32 cap=(u32)args[3].i32(); int32_t buf=args[2].i32(); if(buf&&cap>=out.size()) self->hostcall_write(buf,out); results[0]=Val((int32_t)out.size()); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_password_verify")
return(add([self](Caller caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String password,encoded; self->hostcall_read(args[0].i32(), args[1].i32(), password); self->hostcall_read(args[2].i32(), args[3].i32(), encoded); bool valid=password_verify_native(password,encoded); caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks); results[0]=Val((int32_t)(valid?1:0)); return(std::monostate()); }));
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String password,encoded; self->hostcall_read(args[0].i32(), args[1].i32(), password); self->hostcall_read(args[2].i32(), args[3].i32(), encoded); bool valid=password_verify_native(password,encoded); results[0]=Val((int32_t)(valid?1:0)); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_password_needs_rehash")
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String encoded; self->hostcall_read(args[0].i32(), args[1].i32(), encoded); results[0]=Val((int32_t)(password_needs_rehash_native(encoded)?1:0)); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_log")
@ -2316,7 +2321,6 @@ private:
}
if(buf != 0 && cap >= out.size())
self->hostcall_write(buf, out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)out.size());
return(std::monostate());
}));
@ -2324,7 +2328,7 @@ private:
return(add([self](Caller caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> {
String encoded; self->hostcall_read(args[0].i32(), args[1].i32(), encoded); u32 cap=(u32)args[3].i32(); int32_t buf=args[2].i32(); String out; String stage_key="http:"+encoded;
if(!self->hostcall_staged(stage_key,out)) { DValue req,response; String err; if(ucb_decode(encoded,req,&err)) response=uce_http_request_value(req); else response["error"]="http_request decode failed: "+err; out=ucb_encode(response); if(buf==0) self->hostcall_stage(stage_key,out); }
if(buf&&cap>=out.size()) self->hostcall_write(buf,out); caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks); results[0]=Val((int32_t)out.size()); return(std::monostate());
if(buf&&cap>=out.size()) self->hostcall_write(buf,out); results[0]=Val((int32_t)out.size()); return(std::monostate());
}));
if(mod == "env" && name == "uce_host_http_request_async")
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String encoded; self->hostcall_read(args[0].i32(), args[1].i32(), encoded); DValue req; String err; u64 id=0; if(ucb_decode(encoded,req,&err)) id=uce_http_spawn_spec(req); results[0]=Val((int64_t)id); return(std::monostate()); }));
@ -2335,7 +2339,6 @@ private:
String out; String stage_key="shell_dv:"+encoded;
if(!self->hostcall_staged(stage_key,out)) { DValue spec, response; String err; if(ucb_decode(encoded,spec,&err)) response=uce_shell_exec_spec(spec); else response["error"]="shell_exec spec decode failed: "+err; out=ucb_encode(response); if(buf==0) self->hostcall_stage(stage_key,out); }
if(buf&&cap>=out.size()) self->hostcall_write(buf,out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0]=Val((int32_t)out.size()); return(std::monostate());
}));
if(mod == "env" && name == "uce_host_shell_spawn")
@ -2347,7 +2350,7 @@ private:
if(mod == "env" && name == "uce_host_job_result")
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { String out=ucb_encode(uce_job_result_value((u64)args[0].i64(), 100)); u32 cap=(u32)args[2].i32(); int32_t buf=args[1].i32(); if(buf&&cap>=out.size()) self->hostcall_write(buf,out); results[0]=Val((int32_t)out.size()); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_job_await")
return(add([self](Caller caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { u64 timeout=std::min<u64>((u64)args[1].i64(), 30000); String out=ucb_encode(uce_job_result_value((u64)args[0].i64(), timeout)); u32 cap=(u32)args[3].i32(); int32_t buf=args[2].i32(); if(buf&&cap>=out.size()) self->hostcall_write(buf,out); caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks); results[0]=Val((int32_t)out.size()); return(std::monostate()); }));
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { u64 timeout=std::min<u64>((u64)args[1].i64(), 30000); String out=ucb_encode(uce_job_result_value((u64)args[0].i64(), timeout)); u32 cap=(u32)args[3].i32(); int32_t buf=args[2].i32(); if(buf&&cap>=out.size()) self->hostcall_write(buf,out); results[0]=Val((int32_t)out.size()); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_job_cancel")
return(add([](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> { results[0]=Val((int32_t)(uce_job_cancel_value((u64)args[0].i64())?1:0)); return(std::monostate()); }));
if(mod == "env" && name == "uce_host_path_real")
@ -2823,7 +2826,6 @@ private:
}
if(buf != 0 && cap >= out.size())
self->hostcall_write(buf, out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)out.size());
return(std::monostate());
}));
@ -2922,7 +2924,6 @@ private:
}
if(buf != 0 && cap >= out.size())
self->hostcall_write(buf, out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)out.size());
return(std::monostate());
}));
@ -3033,7 +3034,6 @@ private:
}
if(buf != 0 && cap >= out.size())
self->hostcall_write(buf, out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)out.size());
return(std::monostate());
}));
@ -3074,7 +3074,6 @@ private:
context->resources.sockets.push_back(fd);
}
results[0] = Val((int64_t)(fd > 0 ? fd : 0));
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
return(std::monostate());
}));
if(mod == "env" && name == "uce_host_socket_close")
@ -3115,7 +3114,6 @@ private:
}
if(buf != 0 && cap >= out.size())
self->hostcall_write(buf, out);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)out.size());
return(std::monostate());
}));
@ -3208,7 +3206,6 @@ private:
unsigned int remaining = ::sleep((unsigned int)(usec / 1000000ull));
if(remaining != 0)
{
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)remaining);
return(std::monostate());
}
@ -3216,7 +3213,6 @@ private:
}
if(usec > 0)
::usleep((useconds_t)usec);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
results[0] = Val((int32_t)0);
return(std::monostate());
}));
@ -3275,7 +3271,6 @@ private:
self->hostcall_write(args[6].i32(), resolved);
}
results[0] = Val(slot);
caller.context().set_epoch_deadline(self->worker.cfg.epoch_deadline_ticks);
return(std::monostate());
}));