diff --git a/Cargo.lock b/Cargo.lock index fff8255..f164bbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,6 +881,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "ndk" version = "0.9.0" @@ -1523,6 +1534,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "slab" version = "0.4.12" @@ -1720,6 +1741,31 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "tokio" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.9.12+spec-1.1.0" @@ -1906,6 +1952,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "wasip2" version = "1.0.2+wasi-0.2.9" @@ -2186,6 +2238,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weft-appd" +version = "0.1.0" +dependencies = [ + "anyhow", + "sd-notify", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "weft-build-meta" version = "0.1.0" @@ -2202,6 +2265,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "weft-servo-shell" +version = "0.1.0" +dependencies = [ + "anyhow", + "tracing", + "tracing-subscriber", +] + [[package]] name = "winapi-util" version = "0.1.11" diff --git a/Cargo.toml b/Cargo.toml index 13c6723..534e7d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,10 @@ [workspace] -members = ["crates/weft-build-meta", "crates/weft-compositor", "crates/weft-servo-shell"] +members = [ + "crates/weft-appd", + "crates/weft-build-meta", + "crates/weft-compositor", + "crates/weft-servo-shell", +] resolver = "2" [workspace.package] diff --git a/crates/weft-appd/Cargo.toml b/crates/weft-appd/Cargo.toml new file mode 100644 index 0000000..6261af3 --- /dev/null +++ b/crates/weft-appd/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "weft-appd" +version.workspace = true +edition.workspace = true +rust-version.workspace = true + +[[bin]] +name = "weft-appd" +path = "src/main.rs" + +[dependencies] +anyhow = "1.0" +sd-notify = "0.4" +tokio = { version = "1", features = ["rt", "macros", "signal"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/crates/weft-appd/src/main.rs b/crates/weft-appd/src/main.rs new file mode 100644 index 0000000..1287b2d --- /dev/null +++ b/crates/weft-appd/src/main.rs @@ -0,0 +1,50 @@ +use std::path::PathBuf; + +use anyhow::Context; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::try_from_default_env() + .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), + ) + .init(); + + run().await +} + +async fn run() -> anyhow::Result<()> { + let socket_path = appd_socket_path()?; + tracing::info!(path = %socket_path.display(), "weft-appd IPC socket"); + + // Wave 5 skeleton entry point. + // + // Components to implement (see docu_dev/WEFT-OS-APPD-DESIGN.md): + // AppRegistry — in-memory map of running app sessions and state + // IpcServer — Unix socket at socket_path, serves servo-shell requests + // CompositorClient — Unix socket client to weft-compositor IPC server + // RuntimeSupervisor — spawns and monitors Wasmtime child processes + // CapabilityBroker — resolves manifest permissions to runtime handles + // ResourceController — configures cgroups via systemd transient units + // + // IPC transport: 4-byte LE length-prefixed MessagePack frames. + // Socket path: /run/user//weft/appd.sock (overridable via WEFT_APPD_SOCKET). + // + // sd_notify(READY=1) is sent after IpcServer is bound and CompositorClient + // has established its connection, satisfying Type=notify in weft-appd.service. + anyhow::bail!( + "weft-appd event loop not yet implemented; \ + see docu_dev/WEFT-OS-APPD-DESIGN.md" + ) +} + +fn appd_socket_path() -> anyhow::Result { + if let Ok(p) = std::env::var("WEFT_APPD_SOCKET") { + return Ok(PathBuf::from(p)); + } + + let runtime_dir = std::env::var("XDG_RUNTIME_DIR").context("XDG_RUNTIME_DIR not set")?; + + Ok(PathBuf::from(runtime_dir).join("weft/appd.sock")) +} diff --git a/crates/weft-compositor/src/backend/winit.rs b/crates/weft-compositor/src/backend/winit.rs index 0a44d04..b0b1278 100644 --- a/crates/weft-compositor/src/backend/winit.rs +++ b/crates/weft-compositor/src/backend/winit.rs @@ -20,7 +20,7 @@ use crate::{ }; pub fn run() -> anyhow::Result<()> { - let mut display = smithay::reexports::wayland_server::Display::::new()?; + let display = smithay::reexports::wayland_server::Display::::new()?; let display_handle = display.handle(); let mut event_loop: EventLoop<'static, WeftCompositorState> = EventLoop::try_new()?; @@ -57,7 +57,7 @@ pub fn run() -> anyhow::Result<()> { let listening_socket = ListeningSocketSource::new_auto() .map_err(|e| anyhow::anyhow!("Wayland socket creation failed: {e}"))?; let socket_name = listening_socket.socket_name().to_os_string(); - std::env::set_var("WAYLAND_DISPLAY", &socket_name); + unsafe { std::env::set_var("WAYLAND_DISPLAY", &socket_name) }; tracing::info!(?socket_name, "Wayland compositor socket open"); loop_handle diff --git a/infra/systemd/weft-appd.service b/infra/systemd/weft-appd.service new file mode 100644 index 0000000..823b5c6 --- /dev/null +++ b/infra/systemd/weft-appd.service @@ -0,0 +1,16 @@ +[Unit] +Description=WEFT Application Daemon +Documentation=https://github.com/weft-os/weft +Requires=weft-compositor.service +After=weft-compositor.service servo-shell.service + +[Service] +Type=notify +ExecStart=/packages/system/weft-appd/active/bin/weft-appd +Restart=on-failure +RestartSec=1s +# sd_notify(READY=1) is sent after IpcServer is bound and CompositorClient +# has connected, so downstream services can depend on the IPC socket being ready. + +[Install] +WantedBy=graphical.target