This document details the comprehensive architectural refactoring, optimization, and modernization plan for the asusctl codebase (asusd, asusctl, rog-control-center, and associated sub-crates).
The primary goal of this initiative is code simplification, elimination of async concurrency deadlocks, protocol safety, crate optimization, and a progressive transition toward kernel driver delegation, establishing a robust, testable, and lightweight user-space policy orchestrator.
Commit Baseline: Verified against
OpenGamingCollective/asusctlat commit940dba87(Release6.4.0+, August 2026).
Target MSRV & Edition: Rust 1.85 with Rust Edition 2024 (β Integrated upstream in commits84645b6aand6b6cdc63; establishes[workspace.package]inheritance,unsafe_op_in_unsafe_fnenforcement, and unlocks modern ecosystem dependencies).
Historically, asusctl accumulated custom user-space driver routines (raw WMI calls, raw HID packet crafting, custom powercap limit parsing) and nested concurrency locks (Arc<Mutex<...>>) to work around older Linux kernel limitations.
Recent upstream releases and merges (v6.4.0+) have already resolved several initial pain points:
- β
Rust 1.85 & Edition 2024 Workspace Migration: Upgraded
rust-version = "1.85"andedition = "2024"across all workspace crates (84645b6a,6b6cdc63), updatedclippy.toml(dfe4185b), handledunsafe_op_in_unsafe_fnexplicit blocks, pinned 1.85-compatible dependencies (fontdue = "=0.9.3",slint = "=1.13.1",zbus = "=5.13.2"), and replaced unsafeenv::set_varwithenv_logger::Builder::from_env. - β
Armoury Validation, Persistence & Dynamic Fallbacks (PR #300): Validated hardware writes before modifying in-memory state or disk config (
asusd.ron), added graceful fallback query chain for AC-only defaults (e.g.nv_dynamic_boost: 20) on battery power, and deduplicated PPT group enabling (b4dcb73b,ff36229d,c8f635ce), fixing daemon boot loops (#132). - β
GPU Attributes Idempotency & No-Op Prevention (PR #325): Introduced two-tier idempotency checks for ASUS WMI GPU firmware attributes (e.g.,
dgpu_disable=0), preventing kernel-EIOerrors and shutdown deferred batch aborts during GPU mode transitions (940dba87, fixing #318). - β
ROG Control Center MVI Architecture Overhaul (PR #315): Modernized
rog-control-centerwith a centralized Model-View-Intent state engine (state.rs), unified Tokiompscevent loop inmain.rs, direct channel communication for tray and shortcut portals, and background UI update dispatchers (11f10f37). - β
Global Shortcut Session Restore Grab (PR #312): Re-armed XDG global shortcut portals in
rog-control-centerupon desktop session resume (f13ffbc2,ec2abf28). - β
Workspace Bloat & Dependency Cleanup (PR #321): Purged bloated sub-crates and updated the workspace
Cargo.lock(ede5a396). - π AniMe Matrix Image & Decoding Unification (PR #314): Unifies all image and animation decoders workspace-wide under
image = "=0.25.9", purging legacy direct dependencies (png_pong,pix,gif,png), resolving multi-frame GIF/APNG subframe offset regressions, and streamlining canvas conversions. - π AniMe Matrix Kernel I/O Decoupling & Zero-Copy Proxy (PR #317): Decoupled blocking USB HID kernel I/O from the Tokio async executor using a dedicated background worker thread with a
Condvarmailbox and FIFO control queue. Introduces zero-copy&AnimeDataBufferD-Bus proxy methods (rog-dbus,rog-anime) and frame pre-computation to eliminate D-Bus timeouts and UI stuttering. - β
thiserror v2Workspace Standardization: All workspace crates have been upgraded tothiserror = "^2.0.19". - β
Event-Driven Power/Lid Monitoring: Polling loops in
create_sys_event_taskswere replaced with event-drivenlogind-zbusand a shared udev monitor (fd0abb46/ PR #297). - β
Elimination of UI Runtime Panics: Removed nested Tokio runtime crashes in
rog-control-center(31635a6f/ PR #306). - β
GPU Telemetry Streamlining: Eliminated
lspciprocess spawning, deduplicated udev scans, shared NVML handles, and added runtime power management awareness to avoid waking suspended dGPUs (5823d166/ PR #294).
The remaining roadmap adopts a pragmatic two-track strategy:
- Immediate User-Space Refactoring & Optimization: Modernize daemon internals β eliminate remaining nested
Arc<Mutex<...>>locks via Tokio actors to fix D-Bus deadlocks, replace the legacymiothread and nested Tokio runtimes inaura_manager.rsandstart_power_monitorwith a dedicated synchronous udev worker thread and asynchronous mailbox (mpsc::channel), purging themiodependency without adding external stream crates, decouple code into a clean 3-layer architecture, migrate tooling to native Cargo workspace lints ([workspace.lints]), and introducesysfsprovider traits for non-root CI testing. - Progressive Kernel Offloading: Opportunistically delegate low-level hardware driving to Linux kernel modules (
asus-wmi,asus-armoury,hid-asus,/sys/class/firmware_attributes/) as modern kernel versions (7.0+) become widespread, keeping user-space fallback adapters modular.
All refactoring tasks and PRs must strictly comply with the following invariants:
- Rust 1.85 MSRV & Edition 2024 Baseline: Workspace MSRV is strictly Rust 1.85 with Rust Edition 2024 (now merged upstream). All new code and refactorings must comply with Edition 2024 semantics (e.g.
unsafe_op_in_unsafe_fnby default, RPITIT precise capturinguse<..>, native[workspace.package]inheritance) and avoid unpinned dependencies requiring rustc > 1.85. - "Async Control, Sync Data" Architectural Paradigm: Strictly decouple the asynchronous control plane from synchronous hardware execution. Never execute blocking hardware I/O inside Tokio tasks, and never simulate synchronous polling inside async contexts (e.g. busy loops checking
AtomicBoolor sleeping). Use Tokio strictly for passive event multiplexing (D-Bus, timers, udev events) and offload uninterruptible kernel/USB I/O to dedicated OS worker threads with Condvar/channel mailboxes. - Measurement-Driven Execution: No performance claim is valid without before/after benchmarks. Optimization priority belongs strictly to clean/incremental build times, binary size (
.textsection), RSS memory, timer wakeups (powertop), and protocol correctness. - LOC is an Observation, Not a KPI: Source LOC reduction is recorded for maintainability reporting only. No task may be approved or rejected based on LOC delta alone.
- Zero
.unwrap()Prohibition: Never use.unwrap()in production code. Use proper error propagation (?), pattern matching, or.expect("Clear explanation of invariant"). - Strict
unsafeControl: Avoidunsafeblocks whenever safe Rust abstractions exist. Any mandatoryunsafeblock MUST be preceded by a mandatory// SAFETY:doc comment explaining memory safety invariants (enforced by Edition 2024's defaultunsafe_op_in_unsafe_fnrules). - D-Bus Backward Compatibility: Preserve existing D-Bus method signatures and object paths (
/org/asuslinux/...) so external clients (rog-control-center, GNOME extensions) continue functioning seamlessly. - Native Cargo Workspace Lints: External lint tools (
Cranky.toml) are retired in favor of native[workspace.lints]in rootCargo.toml.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 0: Baseline Benchmark Harness & Environment Setup β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββ 0.1 Reproducible Profiling Protocol (Build time, .text size, RSS) β
β βββ 0.2 Workspace MSRV 1.85 & Edition 2024 Baseline (β
UPSTREAM) β
βββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 1: Immediate User-Space Concurrency & Tooling Modernization β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββ 1.1 State Architecture: Actor Model (Lock Elimination) β
β βββ 1.2 Tooling Modernization: Cranky.toml -> Native [workspace.lints] β
β βββ 1.3 Git Hook Infrastructure: cargo-husky -> Native .githooks β
βββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 2: Architectural Decoupling & Gradual Kernel Offloading β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββ 2.1 Driver vs Daemon Decoupling (3-Layer Architecture) β
β βββ 2.2 Progressive Kernel Offloading & Driver Delegation β
β βββ 2.3 Armoury Attribute Management (Pub/Sub Event System) β
β βββ 2.4 Device Identity & Quirks Engine (`dmi-id` Modernization) β
βββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 3: Protocol Safety, Ergonomics, Event Loop & CLI β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββ 3.1 USB HID Wire Protocol Safety (`zerocopy`) β
β βββ 3.2 PNG & Raster Pipeline Modernization (`rog-anime` image migration)β
β βββ 3.3 Hardware Event Stream & Mailbox (`aura_manager.rs` -> Udev Worker) β
β βββ 3.4 Ergonomic Types & CLI Modernization (`clap` v4, `strum`, flags) β
βββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase 4: Testability, Observability & Automation β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββ 4.1 `sysfs` Abstraction & Hardware Mocking (`SysfsProvider`) β
β βββ 4.2 Asynchronous Observability & Structured Tracing (`tracing`) β
β βββ 4.3 Automated Integration Testing Suite (`uhid-virt` & E2E) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Before undertaking major refactorings, empirical baseline metrics must be recorded into baseline.json:
- Build Time: Clean release build (median of 3 runs) and incremental release build (median of 5 runs).
- Binary Footprint: Executable size,
.textsection size, andcargo bloatoutput fordefault-members(asusd,asusctl,asusd-user,asus-shutdown,rog-control-center). - Runtime Overhead: Idle RSS memory, thread count, CPU usage, open file descriptors, and timer wakeups/sec (
powertop).
- Upstream Integration (
84645b6a,6b6cdc63,dfe4185b):- Set
rust-version = "1.85"andedition = "2024"in[workspace.package]in rootCargo.toml. - Migrated all workspace member crates to Rust Edition 2024, standardizing configuration via
edition.workspace = trueandrust-version.workspace = true. - Handled Edition 2024 compiler requirements:
unsafe_op_in_unsafe_fn: Explicitunsafeblocks placed insideunsafe fn, pairing with our mandatory// SAFETY:doc comment invariant.- Safe Env Logger: Replaced
unsafe { env::set_var(...) }calls withenv_logger::Builder::from_env(...). - Matching Patterns: Fixed irrefutable
if letpattern warnings. - MSRV 1.85 Dependency Pinning: Pinned crates requiring newer rustc (e.g.
fontdue = "=0.9.3"foru*::cast_signed,slint = "=1.13.1",zbus = "=5.13.2"). - Clippy Configuration: Configured
clippy.tomlwithmsrv = "1.85".
- Set
- Refactoring Implications: All subsequent refactoring phases build directly on this stable Edition 2024 baseline.
- Current Issue: The daemon still relies on nested asynchronous concurrent locks (
Arc<Mutex<AuraConfig>>,Arc<Mutex<HidRaw>>,Arc<Mutex<HashMap<...>>>). Inaura_manager.rs, structures likeArc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>cause D-Bus calls to deadlock asynchronously at startup or reload. Furthermore, synchronous USB/HID and sysfs kernel I/O performed directly inside async task loops blocks the Tokio reactor and creates latency jitter on D-Bus. - Refactoring Proposal:
- Implement the "Async Control, Sync Data" Mailbox & Worker Pattern universally across all daemon hardware controllers:
- 1. AniMe Matrix (
asusd::aura_anime,rog-anime): Prototyped and validated in PR #317. Tokio handles frame scheduling and zero-copy D-Bus buffering (&AnimeDataBuffer); a dedicated worker thread with anArc<Condvar>single-slot mailbox executes blocking USB HID transfers. - 2. Aura Keyboard & LED Zones (
asusd::aura_laptop,rog-aura,asusd::aura_manager):- Replaces nested
Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>and inlinehid.lock().await.write(...)calls. - A dedicated sync HID worker thread exclusively owns the
/dev/hidrawhandle and listens to a single-slot mailbox (Arc<(Mutex<Option<LedMatrix>>, Condvar)>). - Tokio animation tasks (Rainbow, Breathe, Pulse, Comet) calculate matrix states and deposit pre-computed frames into the mailbox without holding lock contention over D-Bus setter calls.
- Replaces nested
- 3. Slash Lighting (
asusd::aura_slash,rog-slash):- Replaces
hid: Option<Arc<Mutex<HidRaw>>>andusb: Option<Arc<Mutex<USBRaw>>>. - A dedicated Slash Mailbox worker thread consumes brightness commands and animation packet buffers, completely decoupling USB transfer latency from D-Bus methods.
- Replaces
- 4. ROG Ally Backlight & SCSI (
asusd::aura_scsi,rog-scsi):- Replaces
device: Arc<Mutex<Device>>and blocking raw SCSI command writes (/dev/sg*) inside async D-Bus handlers. - Dedicated SCSI Mailbox worker thread consumes a FIFO command queue and issues uninterruptible SCSI payload blocks off the Tokio reactor.
- Replaces
- 5. Armoury BIOS Attributes & Tuning (
asusd::asus_armoury,rog-platform):- Replaces synchronous sysfs file writes (
/sys/class/firmware_attributes/asus-armoury/attributes/) performed directly within async D-Bus setter handlers. - A dedicated sysfs writer thread consumes a serialized mailbox channel (
tokio::sync::mpsc::channel<(Attribute, AttrValue)>), guaranteeing that ACPI/kernel sysfs delays never stall D-Bus dispatchers.
- Replaces synchronous sysfs file writes (
- 6. Fan Curves & Platform Profiles (
asusd::ctrl_fancurves,asusd::ctrl_platform):- Replaces cross-referencing
Arc<Mutex<Config>>andArc<Mutex<FanCurveConfig>>locks. - Synchronized profile dispatch mailbox receives thermal policy transitions and applies PWM curve tables and PPT power limits sequentially.
- Replaces cross-referencing
- 7. Hardware Udev Hotplug Monitoring (
asusd::aura_manager,start_power_monitor):- Dedicated sync OS thread listens on the kernel netlink udev socket and feeds a
tokio::sync::mpscmailbox, eliminatingmiopolling loops and nestedRuntime::new()instances.
- Dedicated sync OS thread listens on the kernel netlink udev socket and feeds a
- 8. Client Tools & UI (
rog-control-center,asusctl):- Pure async IPC clients interacting via non-blocking D-Bus proxies (
zbus) andtokio::sync::watchtelemetry channels, with zero internal blocking threads or UI freezes.
- Pure async IPC clients interacting via non-blocking D-Bus proxies (
- 1. AniMe Matrix (
- Implement the "Async Control, Sync Data" Mailbox & Worker Pattern universally across all daemon hardware controllers:
- Target Benefits:
- Total elimination of concurrency lock contention and D-Bus deadlocks across all hardware features.
- Clean, deterministic execution flow: zero hardware bus latency leaks into Tokio executor threads.
- 100% testable via mock mailbox receivers and virtual hardware channels without physical hardware.
- Current Issue: The repository uses an external wrapper configuration (
Cranky.toml, 118 lines, 107 clippy error overrides) rather than standard Cargo workspace lint inheritance. - Refactoring Proposal: Migrate all clippy, rustc, and rustdoc policy rules directly into
[workspace.lints.clippy],[workspace.lints.rust], and[workspace.lints.rustdoc]in rootCargo.toml. Member crates inherit policy via[lints] workspace = truealongside[package] edition.workspace = true. - Target Benefits: Zero reliance on external binary wrappers; standard
cargo clippyandcargo checkenforce workspace-wide lint compliance.
- Current Issue:
cargo-huskyadds build-script overhead to dev dependencies for copying git hooks on build. - Refactoring Proposal: Replace
cargo-huskywith native git hooks stored in.githooks/and configured viagit config core.hooksPath .githooks. Ensure CI execution is completely independent of local developer git hooks.
1.4 Crate Consolidation: Deprecate & Purge asusd-user (PR #310)
- Current Status & Rationale:
asusd-userwas originally created as a per-user session daemon.- In current architecture,
asusdexposes all features (Aura, AniMe, Armoury, fan curves) directly on the system D-Bus (/org/asuslinux/...), and all tooling (asusctl,rog-control-center, GNOME extensions) connects exclusively toasusd. - Maintaining
asusd-usercauses dual-daemon packaging confusion, duplicate systemd services, and workspace compile overhead.
- Refactoring Proposal:
- Reopen and integrate PR #310: delete
asusd-user/crate,asusd-user.service, and update distribution packaging scripts (PKGBUILD,Makefile) with upgrade cleanup hooks (cleanup_asusd_leftovers).
- Reopen and integrate PR #310: delete
- Target Benefits:
- Eliminates crate bloat and packaging confusion across distros; reduces total workspace build times.
- Current Issue: Low-level hardware driving logic is tightly coupled within
asusdalongside D-Bus service logic and configuration serialization formats. - Refactoring Proposal: Structurally split the codebase into three distinct layers:
- Adaptor Layer (Driver/Kernel): Standalone modules interfacing with kernel sysfs/WMI interfaces or fallback USB/HID communication.
- Core Engine (Policy & State): The actual daemon, which decides behavioral policies, applies user preferences, and responds to system state changes (power supply, suspend, throttling profiles).
- IPC Layer (D-Bus Interfaces): A thin layer exposing D-Bus interfaces via
zbusand translating remote calls into channel messages for the Core Engine.
- Current Issue: Custom user-space WMI/HID driver routines require ongoing maintenance for each new laptop generation. Upstreaming native kernel drivers takes time, requiring a phased transition.
- Refactoring Proposal:
- Detect available kernel interfaces (
asus-armoury,asus-wmi,/sys/class/firmware_attributes/) at boot viaGetSupported. - Offload hardware operations (e.g. power limits, fan curves, BIOS attributes) to native kernel nodes when present.
- Maintain clean, isolated user-space fallback adapters in the Adaptor Layer for older kernels.
- Detect available kernel interfaces (
- Target Benefits:
- Progressive code cleanup without breaking hardware compatibility on older kernels.
- Seamless transition to kernel-native interfaces as users update their kernels.
2.3 Armoury Attribute Validation, Schema & Persistence (β Integrated Upstream PR #300 & Follow-up PR #301)
- Upstream Integration & Resolved Issue:
- Validate-Before-Persist & Hardware Fallback (β
Merged in PR #300): Sysfs hardware writes are now executed and verified before mutating in-memory
Configor serializing state to/etc/asusd/asusd.ron. If firmware rejects a static AC default (e.g.nv_dynamic_boost: 20on battery),asusdfalls back dynamically to querying the active hardware value (attr.current_value()), and PPT group enablement is deduplicated (b4dcb73b,ff36229d,c8f635ce), resolving issue #132 and preventing boot loops on battery.
- Validate-Before-Persist & Hardware Fallback (β
Merged in PR #300): Sysfs hardware writes are now executed and verified before mutating in-memory
- Remaining Refactoring Opportunities:
- State Serialization Simplification (PR #301): Merge PR #301 to further simplify Armoury attribute JSON serialization and self-healing state restoration.
- Pub/Sub Event Synchronization: Implement Publisher-Subscriber event synchronization: updating an attribute emits an asynchronous
AttributeChangedevent, allowing decoupled handlers (e.g.IntelPowerSync) to respond without polluting core attribute logic.
- Current Issue:
dmi-idis an isolated micro-crate (~80 LOC) that only performs flat string extraction viaudev. ASUS model classification and quirk detection are fragmented and duplicated across 6 crates (asusd,asusctl,rog-control-center,rog-anime,rog-slash,rog-aura) using fragileboard_name.contains(...)string matching. Furthermore, DMI reading lacks a direct/sys/class/dmi/id/filesystem fallback and cannot be mocked without unsafe environment variable hacks, causing tests to be ignored in CI (#[ignore]). - Refactoring Proposal:
- Strongly-Typed ASUS Taxonomy: Centralize model and family parsing into rich domain types (
DeviceFamily,ModelYear,AnimeType,SlashType). - Unified Query APIs: Expose high-level feature checks (
is_rog_ally(),is_tuf(),supported_keyboard_backend(),fan_count()) eliminating duplicate substring matches. - Resilient Dual-Layer DMI Reader: Implement direct
/sys/class/dmi/id/reading with udev enrichment for container and non-udev environments. - 100% Mockable Test Harness: Support
DMIID::from_sysfs_pathandDMIID::mock(...)integrating seamlessly withSysfsProvider(Section 4.1) andsimulatorsfor non-ASUS CI testing. - Workspace Consolidation: Integrate into
rog-platform(or modernize as a full-featured identity engine) to eliminate micro-crate overhead.
- Strongly-Typed ASUS Taxonomy: Centralize model and family parsing into rich domain types (
- Target Benefits:
- Eliminates model parsing duplication and fragile string matching across the workspace.
- Enables offline unit and integration testing of model-specific behavior in CI.
- Sits cleanly between driver detection and daemon policy dispatch.
- Upstream Integration & Recent Fixes:
- GPU Attribute Idempotency & Shutdown Abort Prevention (β
Merged in PR #325): Resolved #318 / #129 by introducing two-tier idempotency checks for ASUS WMI GPU firmware attributes (
dgpu_disable=0). Avoids redundant writes that trigger kernel-EIOerrors, ensuring deferred batch executions (like GPU mode transitions applied during shutdown byasus-shutdown) complete reliably (940dba87).
- GPU Attribute Idempotency & Shutdown Abort Prevention (β
Merged in PR #325): Resolved #318 / #129 by introducing two-tier idempotency checks for ASUS WMI GPU firmware attributes (
- Remaining Refactoring Proposals:
- Dynamic AC/Battery Profile Switching (PR #316): Track and restore preferred platform profiles independently for AC and Battery power sources, seamlessly transitioning via
logindpower supply events. - Missing ACPI Profile Graceful Fallback (PR #280): Prevent daemon startup failures on models where firmware omits the
QuietorLow-Powerprofile.
- Dynamic AC/Battery Profile Switching (PR #316): Track and restore preferred platform profiles independently for AC and Battery power sources, seamlessly transitioning via
- Current Issue:
rog-animeandrog-auraconstruct 640-byte USB HID packets (pub type AnimePacketType = Vec<[u8; 640]>) using manual byte slicing and index offset calculations. - Refactoring Proposal: Use
zerocopyto define strongly-typed HID packet header and payload structures using#[repr(C)]with explicit endian types (U16<LittleEndian>,U32<LittleEndian>) andUnaligned. - Target Benefits:
- Eliminates out-of-bounds slicing crashes.
- Zero-cost serialization/deserialization validated against byte-for-byte golden wire tests.
- Current Status & Reference PR (PR #314):
- Replaced
png_pongandpixsimultaneously withimage(=0.25.9), mapping decoders directly from PNG/APNG toVec<Pixel>forAnimeImage. - Replaced the standalone
gifcrate withimage::codecs::gif::GifDecoder. - Purged
png_pong,pix,gif, and standalonepngfrom workspace dependencies. - Fixed canvas coordinate conversions and subframe offset rendering regressions for animated GIFs and APNGs.
- Replaced
- Target Benefits:
- Consolidates all raster image decoding across the workspace into a single robust dependency (
image). - Eliminates 4 redundant image crates (
png_pong,pix,gif,png). - Verified against golden pixel oracle tests for color luminance, alpha blending, and APNG frame compositing.
- Consolidates all raster image decoding across the workspace into a single robust dependency (
3.3 Hardware Event Stream & Task Lifecycle Modernization (Udev Sync Worker + Mailbox Channel & mio Purge)
- Current Issue:
- In
aura_manager.rs:L583-612, a dedicated OS thread runs amiopolling loop on udev, creates an entire nested Tokio runtime (Runtime::new()), and callsrt.block_on(...)inside the loop for dynamic D-Bus device additions/removals. - In
asusd/src/lib.rs:L134-210(start_power_monitor), a separate dedicated OS thread is spawned purely to pollmiofor power supply changes (AC/Battery) and bridge events to awatch::channel. - The workspace pulls
mio = "^1.2.2"andudev = { ..., features = ["mio"] }solely for these two manual polling loops. - Several background loops across the workspace simulate synchronous behavior within async tasks via
AtomicBoolflags (while running.load(...) { tokio::time::sleep(...) }) or perform blocking syscalls directly on the async executor.
- In
- Refactoring Proposal:
- Udev Sync Worker Thread with Tokio Mailbox Channel (
tokio::sync::mpsc):- Spawn a lightweight, dedicated synchronous OS thread that listens directly to the kernel's netlink udev socket (
udev::MonitorBuilder::new()?.listen()?) via blocking syscalls. - Zero Idle CPU Overhead: The thread sleeps passively inside kernel netlink
recv/pollwith zero timer wakeups and wakes up strictly when the kernel emits a physical hardware event (add,remove,change). - Mailbox Event Dispatch: When a device event occurs (e.g. Aura USB device plugged/unplugged, SCSI device node change, power supply transition), the worker parses the event into a strongly-typed
DeviceHotplugEventenum and sends it over a bounded asynchronous channel (tokio::sync::mpsc::Sender<DeviceHotplugEvent>). - Zero Additional External Crates: Avoids introducing
tokio-udevor complexAsyncFdpolling logic, perfectly embodying the "Async Control, Sync Data" paradigm (synchronous kernel socket listening on an OS worker, asynchronous actor state management on Tokio). - Purge
mioDependency: Completely removemio = "^1.2.2"andudev'smiofeature flag from workspace dependencies. - Eliminate Nested Runtimes: Eradicate secondary
tokio::runtime::Runtimeinstantiations and blocking calls.
- Spawn a lightweight, dedicated synchronous OS thread that listens directly to the kernel's netlink udev socket (
- Workspace-Wide Elimination of
AtomicBoolPolling: Replace all manualAtomicBoolpolling loops acrossasusd,asusd-user, androg-control-centerwithtokio_util::sync::CancellationToken,tokio::sync::watch, andtokio::select!for clean, instant, cooperative task cancellation and hot-reload. - Strict Isolation of Blocking I/O: Guarantee that no task executing on Tokio performs blocking syscalls; all blocking work must be dispatched to sync worker threads or
tokio::task::spawn_blocking(for one-off FS ops).
- Udev Sync Worker Thread with Tokio Mailbox Channel (
- Target Benefits:
- Completely eliminates dedicated blocking
miothreads, nested runtime instantiations, and themioworkspace dependency without adding new third-party async stream crates. - Eliminates timer wakeups caused by artificial polling loops, minimizing idle CPU usage and battery drain.
- Deterministic, zero-overhead task lifecycle management during device hot-unplug and daemon reloads.
- Completely eliminates dedicated blocking
- ROG Control Center MVI Architecture (β
Integrated Upstream PR #315): Modernized
rog-control-centerwith a centralized Model-View-Intent state engine (state.rs), a single Tokiompscevent loop inmain.rs, direct channel communication for tray and shortcut portals, and background telemetry update dispatchers (11f10f37). - Global Shortcut Session Restore Grab (β
Integrated Upstream PR #312): Automatically re-arms XDG global shortcut portal grab listeners upon desktop sleep/resume cycles (
f13ffbc2,ec2abf28). - CLI Framework (
asusctl): Migrate fromarghtoclap(v4 with derive) for improved subcommands, value validation, interactive table rendering (tabled), shell completions (clap_complete), and man pages. - Safe Configuration Loading (PR #305): Ensure config file readers gracefully handle read-only filesystems or unprivileged read permissions without panicking.
- Orphan Example & Target Cleanup (PR #311): Purge obsolete standalone examples in
asusctl/examples/and dev-dependencies to streamline compilation targets. - Enum Conversions (
strum): Applystrumto purely syntactic string-to-enum conversions (e.g.AuraModeNum). - Hardware Capability Flags (
bitflags): Replace raw capability integers and boolean flags with strongly-typedbitflagsstructs for keyboard lighting zones and power modes. - Procfs Reading (
rog-platform): Replace manual string parsing loops in/proc/withprocfsfor reading CPU and thermal information.
- Current Issue: Direct
std::fs::writeandread_to_stringcalls are scattered acrossasusdandrog-platform, preventing unit/integration testing on CI or non-ASUS machines. - Refactoring Proposal: Introduce a
SysfsProvidertrait (RealSysfsfor daemon runtime,MockSysfsfor test environments). - Target Benefits:
- Full test coverage of daemon profile logic and Armoury attribute management without requiring root privileges or physical hardware.
- Reliable CI test execution.
- Current Issue:
asusdhandles concurrent async events using standardlog(env_logger), making it difficult to trace async task execution flows across channels. - Refactoring Proposal: Phased rollout of
tracingandtracing-subscriber, introducing structured spans for D-Bus requests, device hotplug, and state transitions. - Target Benefits:
- Instant identification of async deadlocks, request timeouts, and state transition races.
- Structured log output compatible with
systemd-journald.
- Refactoring Proposal: Create an E2E integration test runner using
uhid-virtand virtual D-Bus session buses to testasusctlCLI commands against a live daemon instance in CI.
When refactoring daemon components, the following architectural patterns must be preserved and updated to actor/task abstractions:
Rather than an arbitrary hybrid, the decoupled model is the idiomatic Rust systems pattern for hardware control:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TOKIO ASYNC CONTROL PLANE β
β β
β βββββββββββββββββββ ββββββββββββββββββββββ βββββββββββββββββββ β
β β D-Bus (zbus) β β Animation Timers / β β System Events β β
β β System Service β β Frame Schedulers β β(Udev Mailbox Rx)β β
β ββββββββββ¬βββββββββ βββββββββββ¬βββββββββββ ββββββββββ¬βββββββββ β
β β β β β
β βΌ βΌ βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Cooperative Task Multiplexing & Actor Dispatch β β
β β (tokio::select!, CancellationToken, tokio::sync::watch) β β
β βββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β Single-Slot Mailbox / FIFO Queue
β (&DataBuffer, Arc<Condvar>, mpsc)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HARDWARE WORKER PLANE (OS THREADS) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Dedicated Sync Worker Thread (std::thread / Mailbox) β β
β β β β
β β β’ Uninterruptible blocking USB HID writes (rusb / hidraw) β β
β β β’ Blocking sysfs / WMI kernel file operations β |
β β β’ Blocking kernel netlink udev socket listener (Mailbox Tx) β β
β β β’ Zero latency jitter leaked to Tokio async reactor β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Tokio Control Plane (Network & System Coordination):
- Scope: D-Bus daemon endpoints (
zbus), animation frame tick timers (tokio::time::interval), configuration file watching, system signals (logind-zbus, udev mailbox receiver channel), and client request validation. - Characteristics: Ultra-lightweight passive event waiting. Handles concurrent client calls without blocking.
- Scope: D-Bus daemon endpoints (
- Mailbox / OS Thread Worker Plane (Hardware Data I/O):
- Scope: Low-level USB HID transfers (
rog-anime,rog-aura), raw SCSI commands (rog-scsi), and sysfs kernel attribute writes (asus-armoury). - Characteristics: Receives ready/pre-computed data buffers and executes uninterruptible, blocking kernel/USB calls in dedicated OS threads, keeping hardware bus latency and transfer delays isolated from D-Bus and the async reactor.
- Scope: Low-level USB HID transfers (
Rather than removing the async executor, maximizing Tokio's performance requires eliminating anti-patterns that simulate synchronous behavior in async tasks:
- β Eliminate
AtomicBoolPolling Loops: Never runwhile atomic_flag.load(...) { tokio::time::sleep(...) }inside async tasks. - β
Adopt Event-Driven Synchronization: Use
tokio_util::sync::CancellationToken,tokio::sync::watch, ortokio::select!for cooperative cancellation and immediate state change propagation. - β Eliminate Blocking Calls in Async Handlers: Never execute raw
rusbwrites,std::thread::sleep, or synchronous file I/O within async task handlers. - β
Decouple via Mailboxes & Channels: Forward commands and buffers to dedicated synchronous worker threads via
Condvarmailboxes (as implemented in PR #317) or bounded channels.
GetSupported: Checks hardware/kernel features before controller initialization.Reloadable: Reloads configuration and state dynamically without restartingasusd.CtrlTask: Runs background tasks, monitors system signals (suspend/resume/boot), and watches configuration paths.ZbusAdd: Exposes controller interfaces cleanly on the system bus viazbus.
- Avoid wrapping controllers in
Arc<Mutex<T>>. - Route external D-Bus invocations and background tasks through Tokio
mpscchannels or Mailbox workers owning the controller state. - If an async lock is strictly required in legacy task loops, use non-blocking
try_lock()inside task event callbacks to prevent deadlocks when system events fire concurrently.
| Improvement / Candidate Crate | Status / Scope | Priority | Target Benefit |
|---|---|---|---|
thiserror v2 Uniformity |
β INTEGRATED UPSTREAM | β | thiserror = "^2.0.19" standardized across all workspace crates in v6.4.0. |
| Event-Driven Sys Monitors | β INTEGRATED UPSTREAM | β | Polling loops replaced by logind-zbus & udev monitor in create_sys_event_tasks. |
| GPU Telemetry Optimization | β INTEGRATED UPSTREAM | β | Eliminated lspci spawning, shared NVML handle, runtime PM awareness. |
| Rust 1.85 & Edition 2024 | β INTEGRATED UPSTREAM | β | Upgraded workspace MSRV to 1.85 & Edition 2024 across all crates (84645b6a, 6b6cdc63, dfe4185b). |
[workspace.lints.clippy] |
π’ APPROVED | π΄ P0 | Native Cargo workspace lint policy replacing Cranky.toml. |
cargo-husky β .githooks |
π’ APPROVED | π P1 | Native git hooks script; decouples CI from local dev build hooks. |
Deprecate & Purge asusd-user |
βΉοΈ REOPEN / MERGE (#310) | π P1 | Removes obsolete user daemon crate, dual services, and packaging bloat. |
Udev Worker & Mailbox Channel (mio Purge) |
π’ APPROVED | π P1 | Replaces blocking mio threads in aura_manager.rs & start_power_monitor with a sync worker thread and Tokio mpsc mailbox; removes mio and nested Tokio runtimes without adding external stream crates. |
Unified Image Pipeline (image) |
π PR OPEN (#314) | π P1 | Unified PNG/APNG/GIF decoding under image = "=0.25.9"; purges png_pong, pix, gif, and png. |
| AniMe Kernel I/O Decoupling | π PR OPEN (#317) | π P1 | Decouples USB HID I/O with Condvar mailbox worker thread, FIFO queue, &AnimeDataBuffer zero-copy proxy, frame pre-computation. |
| Armoury Validation & Fallback | β INTEGRATED UPSTREAM (#300) | β | Validates sysfs writes before config mutation & adds dynamic hardware fallback query on battery (b4dcb73b, ff36229d, c8f635ce). |
| GPU Attributes Idempotency | β INTEGRATED UPSTREAM (#325) | β | Two-tier idempotency checks for GPU attributes (e.g. dgpu_disable=0), preventing kernel -EIO errors & shutdown aborts (940dba87). |
| ROG Control Center MVI Architecture | β INTEGRATED UPSTREAM (#315) | β | Model-View-Intent event-driven architecture, central state.rs engine, single tokio::sync::mpsc event loop (11f10f37). |
| Workspace Bloat & Crate Cleanup | β INTEGRATED UPSTREAM (#321) | β | Purged bloated sub-crates and updated the workspace Cargo.lock (ede5a396). |
| Armoury State JSON Simplification | π PR OPEN (#301) | π P1 | Simplifies JSON state serialization & boot restoration logic. |
| Platform Profile per Power Source | π PR OPEN (#316) | π P1 | Independent AC / Battery profile memory and automatic switching on power transitions. |
| Missing ACPI Profile Fallback | π PR OPEN (#280) | π P1 | Graceful fallback when firmware lacks Quiet/Low-Power profiles to prevent daemon crashes. |
| Safe Config Loading (Read-Only) | π PR OPEN (#305) | π P1 | Prevents crashes when reading configs on read-only filesystems or restricted permissions. |
zerocopy |
π’ APPROVED (PoC Narrow) | π P1 | Type-safe USB HID 640-byte packet definition in rog-anime & rog-aura. |
Device Identity Engine (dmi-id) |
π’ APPROVED | π P1 | Centralize DMI taxonomy & model parsing; eliminate duplicate board_name matching; add sysfs fallback & mockability. |
argh β clap (v4) |
π’ APPROVED (Bench First) | π P1 | CLI overhaul for asusctl (subcommands, completions, validation). |
strum |
π’ APPROVED (Targeted) | π P1 | Replaces duplicate string/enum matches for syntactic enums (AuraModeNum). |
bitflags |
π’ APPROVED (Targeted) | π P1 | Typed bitmasks for hardware capability zones and power features. |
| Global Shortcuts Grab on Restore | β INTEGRATED UPSTREAM (#312) | β | Re-arms XDG global shortcut portals in rog-control-center upon desktop session resume (f13ffbc2, ec2abf28). |
tracing |
π’ APPROVED (Phased) | π‘ P2 | Structured async tracing for D-Bus requests, udev, and state transitions. |
SysfsProvider Mocking |
π’ APPROVED | π‘ P2 | Trait-based sysfs abstraction for non-root CI and hardware simulation. |
tabled |
βͺ OPTIONAL UX | π‘ P2 | Formatted table output for asusctl CLI status commands. |
procfs |
βͺ TARGETED | π‘ P2 | Replaces manual /proc/ string parsing in rog-platform for CPU/thermal info. |
tokio-util (CancellationToken) |
π’ APPROVED | π P1 | Replaces AtomicBool loops workspace-wide with CancellationToken; eliminates polling wakeups. |