Skip to content

fix(tauri): harden Windows pre-CEF single-instance mutex handling#2669

Merged
graycyrus merged 2 commits into
tinyhumansai:mainfrom
YellowSnnowmann:fix/windows-pre-cef-mutex-hardening
May 27, 2026
Merged

fix(tauri): harden Windows pre-CEF single-instance mutex handling#2669
graycyrus merged 2 commits into
tinyhumansai:mainfrom
YellowSnnowmann:fix/windows-pre-cef-mutex-hardening

Conversation

@YellowSnnowmann
Copy link
Copy Markdown
Contributor

@YellowSnnowmann YellowSnnowmann commented May 26, 2026

Summary

  • Hardens the Windows pre-CEF single-instance guard in app/src-tauri/src/lib.rs to better handle Win32 edge cases.

  • Captures GetLastError() immediately after CreateMutexW so the mutex result cannot be clobbered by later calls.

  • Adds explicit CreateMutexW == NULL handling with an error log and best-effort continuation.

  • Preserves existing secondary-instance early-exit behavior (ERROR_ALREADY_EXISTS) and deep-link forwarding path.

Problem

  • On Windows, this guard exists to prevent secondary launches from reaching cef::initialize() and triggering the known panic path (OPENHUMAN-TAURI-A).

  • The previous logic relied on reading GetLastError() inline and did not explicitly handle a NULL mutex handle path with strong observability.

  • That made rare Win32 failure modes harder to diagnose and increased risk of unclear startup behavior during concurrency.

Solution

  • Read and store last_error immediately after CreateMutexW.

  • Branch explicitly for handle.is_null(), log the Win32 error, and continue startup best-effort rather than crashing early.

  • Keep the ERROR_ALREADY_EXISTS branch as the authoritative secondary-instance exit path, including deep-link forwarding attempt before exit.

  • Retain RAII mutex ownership for the primary instance so handle lifetime is clean and deterministic.

Submission Checklist

  • If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy

  • Diff coverage ≥ 80% — changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/coverage.yml. Run pnpm test:coverage and pnpm test:rust locally; PRs below 80% on changed lines will not merge.

  • Coverage matrix updated — added/removed/renamed feature rows in docs/TEST-COVERAGE-MATRIX.md reflect this change (or N/A: behaviour-only change)

  • All affected feature IDs from the matrix are listed in the PR description under ## Related

  • No new external network dependencies introduced (mock backend used per Testing Strategy)

  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md)

  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Platform/runtime: Windows desktop Tauri startup path only; no intended behavior change on macOS/Linux.

  • Security/compatibility: improves failure observability and startup robustness; no API or config migration required.

  • Performance: negligible (one extra error-code capture and logging only on failure path).

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for Windows single-instance enforcement to prevent application crashes when multiple instances attempt to launch simultaneously. Enhanced logging and resource management for better stability.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4246513b-a0bb-4d4d-9c99-4eecad3f500e

📥 Commits

Reviewing files that changed from the base of the PR and between e7e7e8a and 058bcd9.

📒 Files selected for processing (1)
  • app/src-tauri/src/lib.rs

📝 Walkthrough

Walkthrough

The Windows single-instance mutex guard in run() now captures GetLastError() immediately after CreateMutexW instead of deferring it, introduces an OwnedMutex RAII guard for handle lifetime, and properly handles both NULL handle and already-exists cases with explicit cleanup and captured error values.

Changes

Windows mutex error handling

Layer / File(s) Summary
Windows single-instance mutex guard error handling
app/src-tauri/src/lib.rs
GetLastError() is captured immediately after CreateMutexW into a local variable. OwnedMutex RAII struct manages handle lifetime. On NULL handle, the code logs the captured error and continues safely. On "already exists" detection, the code explicitly closes the secondary's handle and exits using the captured error value rather than re-reading GetLastError().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2469: Both PRs modify the Windows pre-CEF single-instance/mutex guard flow in app/src-tauri/src/lib.rs—one fixes mutex GetLastError/handle handling, and the other uses the "mutex already held" path to forward deep-link/OAuth callbacks via the new named-pipe IPC.
  • tinyhumansai/openhuman#1723: Both PRs modify the Windows pre-CEF single-instance mutex guard in app/src-tauri/src/lib.rs (run()), specifically around CreateMutexW/ERROR_ALREADY_EXISTS handling and mutex handle lifecycle/error (GetLastError) behavior.

Suggested labels

bug

Suggested reviewers

  • graycyrus
  • M3gA-Mind

Poem

🐰 A mutex guard stood tall and proud,
But GetLastError played in a crowd—
Windows API whispered a tale of timing,
So we captured it right, now errors shine bright! 🎯
RAII holds the door, cleanup's delight! 🚪

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(tauri): harden Windows pre-CEF single-instance mutex handling' directly and specifically describes the main change: hardening Windows mutex handling for single-instance enforcement.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


Comment @coderabbitai help to get the list of available commands and usage tips.

@YellowSnnowmann YellowSnnowmann marked this pull request as ready for review May 26, 2026 10:05
@YellowSnnowmann YellowSnnowmann requested a review from a team May 26, 2026 10:05
@coderabbitai coderabbitai Bot added the bug label May 26, 2026
@graycyrus graycyrus merged commit f946eda into tinyhumansai:main May 27, 2026
36 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants