//! `WorkerArgs` (the pump's constructor payload) and `reject_from_close`. use super::*; use crate::config::{CompositorPref, GamepadPref, Mode}; use crate::error::Result; use crate::input::InputEvent; use crate::quic::{HdrMeta, HidOutput, RichInput}; use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU64}; use std::sync::mpsc::SyncSender; use std::sync::{Arc, Mutex}; pub(crate) struct WorkerArgs { pub(crate) host: String, pub(crate) port: u16, pub(crate) mode: Mode, pub(crate) compositor: CompositorPref, pub(crate) gamepad: GamepadPref, pub(crate) bitrate_kbps: u32, pub(crate) video_caps: u8, pub(crate) audio_channels: u8, pub(crate) video_codecs: u8, pub(crate) preferred_codec: u8, pub(crate) display_hdr: Option, pub(crate) launch: Option, pub(crate) pin: Option<[u8; 32]>, pub(crate) identity: Option<(String, String)>, pub(crate) frames: Arc, pub(crate) audio_tx: SyncSender, pub(crate) rumble_tx: SyncSender, /// Feed half of the rumble policy engine — its `Drop` (demux task end) marks the engine /// closed, so the command API always observes connection teardown. pub(crate) rumble_feed: super::rumble::RumbleFeed, pub(crate) hidout_tx: SyncSender, pub(crate) hdr_meta_tx: SyncSender, pub(crate) host_timing_tx: SyncSender, pub(crate) input_rx: tokio::sync::mpsc::UnboundedReceiver, pub(crate) mic_rx: tokio::sync::mpsc::Receiver<(u32, u64, Vec)>, pub(crate) rich_input_rx: tokio::sync::mpsc::UnboundedReceiver, pub(crate) ctrl_rx: tokio::sync::mpsc::Receiver, pub(crate) ctrl_tx: tokio::sync::mpsc::Sender, pub(crate) ready_tx: std::sync::mpsc::Sender>, pub(crate) shutdown: Arc, /// Deliberate-quit flag (see [`NativeClient::quit`]): the worker closes with the quit code if set. pub(crate) quit: Arc, pub(crate) mode_slot: Arc>, pub(crate) probe: Arc>, pub(crate) frames_dropped: Arc, pub(crate) fec_recovered: Arc, pub(crate) hot_tids: Arc>>, /// The live clock offset (see [`NativeClient::clock_offset`]): the worker seeds it with the /// connect-time estimate; the control task's mid-stream re-syncs update it. pub(crate) clock_offset: Arc, /// Decode-stage latency samples from the embedder (see [`NativeClient::decode_lat`]): the pump /// drains a window mean into the adaptive-bitrate controller's decode signal. pub(crate) decode_lat: Arc>, } /// The worker: QUIC handshake, then the input/datagram/control tasks + the blocking /// data-plane pump. /// The host's stated rejection, if this connection was closed with a typed application code /// (see [`crate::reject`]) — `None` for local errors, bare/legacy closes (including our own /// `LocallyClosed`), and transport failures, which keep their original error. pub(crate) fn reject_from_close(conn: &quinn::Connection) -> Option { match conn.close_reason()? { quinn::ConnectionError::ApplicationClosed(ac) => u32::try_from(u64::from(ac.error_code)) .ok() .and_then(crate::reject::RejectReason::from_close_code), _ => None, } }