Skip to content

fix(window-state): avoid save deadlock during resize (fix #3594) - #3727

Draft
Sealdot wants to merge 1 commit into
tauri-apps:v2from
Sealdot:codex/fix-window-state-save-deadlock-3594
Draft

Sealdot wants to merge 1 commit into
tauri-apps:v2from
Sealdot:codex/fix-window-state-save-deadlock-3594

Conversation

@Sealdot

@Sealdot Sealdot commented Oct 23, 2026

Copy link
Copy Markdown

Fixes #3594.

Calling the asynchronous saveWindowState command while resize/move events are processed can deadlock: the worker holds WindowStateCache while waiting for a native getter, and the event loop waits for that cache lock.

Dispatch the command's existing save operation to the main thread and await its result. Validate flags before dispatch and propagate scheduling, save and dropped-task errors. This avoids replacing the cache from a stale snapshot. Add a running MockRuntime regression for the execution thread, serialized state, filesystem failures and invalid flags, plus paired Rust/JS patch changesets.

Verified locally on macOS 27.0.1 arm64 with Rust 1.97.1, Tauri 2.12.0, Wry 0.57.0 and Tao 0.37.1, based on df594206ce03f67e25da04283dea023815a45058:

  • The same regression fails against the original command's worker execution and passes with the candidate.
  • A standalone native WebView app makes the real plugin IPC call with flags 63. The original command completes 9,230 saves without the resize loop, but hangs with concurrent resizes. A process sample shows the main event callback waiting on the cache mutex while a worker waits for is_minimized to return through the event loop.
  • The final candidate completes 16,544 saves and 4,419 programmatic resizes in a bounded 20-second run, writes matching final physical dimensions, and exits normally. Four concurrent save loops are used; this is a functional check, not a performance benchmark.
  • cargo test --locked --offline -p tauri-plugin-window-state --all-targets --all-features: 1 regression passed.
  • cargo clippy --locked --offline -p tauri-plugin-window-state --all-targets --all-features -- -D warnings: passed.
  • cargo +1.90.0 check --locked --offline -p tauri-plugin-window-state: passed.
  • cargo test --locked --offline -p tauri-plugin-window-state --doc: command passed, 0 doc tests.
  • Workspace Rust formatting, changed TOML formatting, changeset/license checks, changeset Prettier and whitespace checks passed.

The synchronous Rust API and exit-time save behavior stay as before. Direct worker calls through that API remain outside this fix. The save still performs synchronous filesystem I/O on the main thread; there is no new guarantee about latency or draining queued saves at shutdown. Windows/Linux/mobile, manual move/title-bar zoom and the official WebDriver suite were not run.

AI assistance: Codex helped with implementation, test design and internal code review. The results above were executed locally; they are not upstream CI results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[window-state] saveWindowState deadlocks when a resize or move event arrives during the save (still reproduces after tao#1182)

1 participant