Skip to content

refactor: replace tokio::sync::Mutex with std::sync::Mutex for non-IO data#9176

Merged
shulaoda merged 1 commit intomainfrom
04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data
Apr 27, 2026
Merged

refactor: replace tokio::sync::Mutex with std::sync::Mutex for non-IO data#9176
shulaoda merged 1 commit intomainfrom
04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data

Conversation

@shulaoda
Copy link
Copy Markdown
Member

@shulaoda shulaoda commented Apr 21, 2026

Summary

  • Replace tokio::sync::Mutex with std::sync::Mutex for two places that only guard plain data and never hold the lock across an .await point:
    • PluginDriver.tx / NativePluginContextImpl.txArc<Mutex<Option<UnboundedSender<ModuleLoaderMsg>>>>
    • BundleCoordinator.watcherMutex<DynFsWatcher>
  • De-async PluginDriver::set_context_load_modules_tx as a consequence, and drop the redundant .await at its two call sites in ScanStage.

Why

Per tokio's own guidance, the async mutex should be reserved for protecting IO resources where the lock genuinely needs to be held across .await. For plain data the blocking std::sync::Mutex is both cheaper and less prone to latent deadlocks when used through sync NAPI bindings. This continues the migration started in #9031 (which collapsed the FileEmitter.tx path to sync for the emit_chunk deadlock fix).

Scope of this change:

  • PluginDriver.tx is only ever acquired to clone an Option<UnboundedSender> and to swap a new sender in at scan boundaries. The existing code in NativePluginContextImpl::load already drops the guard before awaiting sender.send(...); the only reason it used tokio::sync::Mutex was incidental. Switching to std::sync::Mutex makes that invariant syntactically enforced (no .await possible while the guard is live) and lets set_context_load_modules_tx shed its unnecessary async marker.
  • BundleCoordinator.watcher is used exclusively inside update_watch_paths, where the guard is held only over synchronous paths_mut.add(...) / paths_mut.commit() calls. No .await exists in that critical section, so async mutex is pure overhead here.

No behavioral change for plugin authors or bundler consumers, the JS APIs and message flows are unchanged.

Refs

Copy link
Copy Markdown
Member Author


How to use the Graphite Merge Queue

Add the label graphite: merge-when-ready to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 21, 2026

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit 2c1f4c1
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/69ef2186828c3d0008419d40

@shulaoda shulaoda force-pushed the 04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data branch 4 times, most recently from 70fa928 to d49a834 Compare April 21, 2026 02:25
@shulaoda shulaoda marked this pull request as ready for review April 21, 2026 02:37
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 21, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing 04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data (2c1f4c1) with main (27026df)

Open in CodSpeed

Footnotes

  1. 10 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@shulaoda shulaoda marked this pull request as draft April 22, 2026 02:19
@shulaoda shulaoda marked this pull request as ready for review April 24, 2026 06:39
@shulaoda shulaoda marked this pull request as draft April 24, 2026 06:58
@shulaoda shulaoda force-pushed the 04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data branch from a204c29 to 2c1f4c1 Compare April 27, 2026 08:42
@shulaoda shulaoda marked this pull request as ready for review April 27, 2026 08:43
@shulaoda shulaoda merged commit 9f42ff3 into main Apr 27, 2026
57 of 58 checks passed
@shulaoda shulaoda deleted the 04-21-refactor_replace_tokio_sync_mutex_with_std_sync_mutex_for_non-io_data branch April 27, 2026 09:30
This was referenced Apr 29, 2026
shulaoda added a commit that referenced this pull request Apr 29, 2026
## [1.0.0-rc.18] - 2026-04-29

### 💥 BREAKING CHANGES

- optimization: default unspecified inlineConst.mode to smart (#9248) by @IWANABETHATGUY

### 🐛 Bug Fixes

- rolldown_plugin_vite_import_glob: return error instead of panicking when virtual module uses a relative glob (#9241) by @shulaoda
- binding: treat empty inlineConst object as omitted (#9247) by @IWANABETHATGUY
- rolldown: keep enum declaration for optional-chain access (#9229) by @Dunqing
- link_stage: restore inline let-else in exports-kind filter (#9237) by @IWANABETHATGUY
- dev/lazy: avoid module reinitialization in lazy compilation patches (#9179) by @h-a-n-a
- dev: visit identifier references for runtime rewrites in HMR finalizer (#9191) by @h-a-n-a
- chunk-optimizer: pick dominator for runtime placement to avoid cycles (#9164) by @IWANABETHATGUY
- make `this.emitFile` chunk path synchronous to avoid deadlock (#9031) by @lazarv
- use sentinel id for `browser: false` ignored modules (#9192) by @shulaoda
- prevent chunk optimizer from creating import cycles (#9228) by @IWANABETHATGUY

### 🚜 Refactor

- replace tokio::sync::Mutex with std::sync::Mutex for non-IO data (#9176) by @shulaoda
- rolldown_plugin_vite_import_glob: do not rewrite import path for absolute base (#9195) by @shulaoda
- runtime_helper: wrap DependedRuntimeHelperMap in a struct (#9215) by @IWANABETHATGUY
- drop redundant clear() in determine_safely_merge_cjs_ns (#9206) by @IWANABETHATGUY
- clean up generate_lazy_export (#9208) by @IWANABETHATGUY
- bitset: return bool from set_bit to fuse guard-and-set (#9207) by @IWANABETHATGUY
- link_stage: simplify exports-kind filter and clarify safety comments (#9205) by @IWANABETHATGUY

### 📚 Documentation

- determine_module_exports_kind (#9252) by @IWANABETHATGUY
- fix dead link to esbuild ESM/CJS interop tests (#9230) by @Copilot
- remove CSS bundling references (#9234) by @shulaoda
- correct IncrementalFullBuild row in BundleMode table (#9214) by @IWANABETHATGUY
- design: add bundler data lifecycle design doc (#9212) by @hyf0
- remove minifier alpha status notices (#9202) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- upgrade oxc to 0.128.0 (#9260) by @shulaoda
- deps: bump rolldown-ariadne to 0.6.0 (#9254) by @IWANABETHATGUY
- deps: update github actions (#9259) by @renovate[bot]
- deps: update github actions (#9258) by @renovate[bot]
- remove renovate overrides (#9257) by @Boshen
- use ubuntu-latest for security workflow (#9256) by @Boshen
- notify Discord around release publish (#9251) by @Boshen
- add release environment to npm publish workflow (#9250) by @Boshen
- justfile: drop the `--` separator before forwarded args in `vp run` (#9246) by @shulaoda
- deps: update test262 submodule for tests (#9243) by @sapphi-red
- add more tracing instrumentations (#9220) by @sapphi-red
- rolldown_plugin_vite_import_glob: remove outdated sourcemap doc comment (#9213) by @shulaoda
- update security workflow (#9201) by @Boshen

### ❤️ New Contributors

* @lazarv made their first contribution in [#9031](#9031)

Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
@rolldown-guard rolldown-guard Bot mentioned this pull request Apr 29, 2026
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.

2 participants