feat(init): watchdog: pinger thread PINGs servers (framework answers, no server code), main kills after 5s unanswered -> crash path; not pinged: terminal, pm (handlers wait for user); give-up drains queued ping; spawntest hang check

This commit is contained in:
2026-10-28 01:51:39 +01:00
parent 28f1ace00a
commit 3d69c10079
9 changed files with 236 additions and 18 deletions

View File

@@ -7,4 +7,4 @@ pub mod server;
pub use codec::{Decode, Encode};
pub use executor::block_on;
pub use server::{MALFORMED, Server, serve};
pub use server::{MALFORMED, PING, Server, serve};

View File

@@ -9,6 +9,11 @@ use types::bounded::CapSlot;
/// tag, so every client decodes it as an error.
pub const MALFORMED: usize = usize::MAX;
/// Init's watchdog asking whether the server still serves: answered with
/// the same word by the loop itself, never seen by the server's code. No
/// protocol uses it either.
pub const PING: usize = usize::MAX - 1;
pub trait Server {
type Request: Decode;
type Response: Encode;
@@ -37,8 +42,9 @@ pub trait Server {
/// Serves `endpoint` until receiving on it fails (it was destroyed or
/// the capability revoked), then returns why. Every `Call` gets a
/// reply, `[MALFORMED, ..]` if it does not decode; a one-way `Send` is
/// handled without one; notification signals go to `signal`.
/// reply, `[MALFORMED, ..]` if it does not decode, `[PING, ..]` to a
/// `PING`; a one-way `Send` is handled without one; notification
/// signals go to `signal`.
fn run(&mut self, endpoint: CapSlot) -> libkos::syscall::Error {
use libkos::syscall::{Received, receive_msg, reply_recv};
let mut next = receive_msg(endpoint);
@@ -48,6 +54,7 @@ pub trait Server {
Err(e) => return e,
};
next = match message {
Received::Call { words, .. } if words[0] == PING => reply_recv(endpoint, [PING, 0, 0, 0], None),
Received::Call { badge, words, cap } => {
let (reply, give) = self.handle_call(badge, words, cap);
reply_recv(endpoint, reply, give)