Skip to content

Conversation

@alexcrichton
Copy link
Member

@alexcrichton alexcrichton commented Oct 10, 2025

This commit is a large change to the implementation of filesystem and
other system-related operations on WASI targets. Previously the standard
library explicitly used the wasi crate at the 0.11.x version track
which means that it used WASIp1 APIs directly. This meant that std was
hard-coded to use WASIp1 syscalls and there was no separate
implementation for the WASIp{2,3} targets, for example. The high-level
goal of this commit is to decouple this interaction and avoid the use of
the wasi crate on the WASIp2 target.

Historically when WASIp1 was originally added to Rust the wasi-libc
library was in a much different position than it is today. Nowadays Rust
already depends on wasi-libc on WASI targets for things like memory
allocation and environment variable management. As a libc library it
also has all the functions necessary to implement all filesystem
operations Rust wants. Recently wasi-libc additionally was updated to
use WASIp2 APIs directly on the wasm32-wasip2 target instead of using
wasm32-wasip1 APIs. This commit is leveraging this work by enabling
Rust to completely sever the dependence on WASIp1 APIs when compiling
for wasm32-wasip2. This is also intended to make it easier to migrate
to wasm32-wasip3 internally in the future where now only libc need be
updated and Rust doesn't need to explicitly change as well.

The overall premise of this commit is that there's no need for
WASI-specific implementation modules throughout the standard library.
Instead the libc-style bindings already implemented for Unix-like
targets are sufficient. This means that Rust will now be using
libc-style interfaces to interact with the filesystem, for example, and
wasi-libc is the one responsible for translating these POSIX-ish
functions into WASIp{1,2} calls.

Concrete changes here are:

  • std for wasm32-wasip2 no longer depends on wasi 0.11.x
  • The implementation of std::os::wasi::fs, which was previously
    unstable and still is, now has portions gated to only work on the
    WASIp1 target which use the wasi crate directly. Traits have been
    trimmed down in some cases, updated in others, or now present a
    different API on WASIp1 and WASIp2. It's expected this'll get further
    cleanup in the future.
  • The std::sys::fd::wasi module is deleted and unix is used instead.
  • The std::sys::fs::wasi module is deleted and unix is used instead.
  • The std::sys::io::io_slice::wasi module is deleted and unix is used
    instead.
  • The std::sys::pal::{wasip1,wasip2} modules are now merged together
    as their difference is much smaller than before.
  • The std::sys::pal::wasi::time is deleted and the unix variant is
    used directly instead.
  • The std::sys::stdio::wasip{1,2} modules are deleted and the unix
    variant is used instead.
  • The std::sys::thread::wasip{1,2} modules are deleted and the unix
    variant is used instead.

Overall Rust's libstd is effectively more tightly bound to libc when
compiled to WASI targets. This is intended to mirror how it's expected
all other languages will also bind to WASI. This additionally has the
nice goal of drastically reducing the WASI-specific maintenance burden
in libstd (in theory) and the only real changes required here are extra
definitions being added to libc (done in separate PRs). This might be
required for more symbols in the future but for now everything should be
mostly complete.

@rustbot rustbot added O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 10, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 10, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added A-rustdoc-search Area: Rustdoc's search feature T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Oct 10, 2025
@Mark-Simulacrum
Copy link
Member

At a high level this seems OK (cc @joboet as you've been working on a bunch of sys cleanups).

If I'm understanding the new code right, it looks like the future we'd expect is to remove the wasi modules entirely in favor of wasipN being cfg(unix) for the most part? Does that understanding seem right? I see that a bunch of the code "added" here seems like it's copy/paste from cfg(unix) modules counterparts.

For example, maybe library/std/src/sys/io/io_slice/wasi.rs should already be removed and cfgs rerouted to the iovec module, with the extra methods gated on cfgs in that? I think that would also apply to other similar modules at this point. Diffing locally (diff -u <(git show cb4a430b8349d9216f2c58d921a1b3a5aa6a6652:library/std/src/sys/io/io_slice/wasi.rs) library/std/src/sys/io/io_slice/iovec.rs | less) it seems like the only real difference is the extra conversion methods.

@alexcrichton
Copy link
Member Author

That's a good point! You have also made me realize that most of the fs implementation is entirely redundant as well. Almost all of the functions the unix variant uses are implemented by wasi-libc which means we could use wasi-libc directly. The original reason for wasi having its own implementation was to implement everything natively in Rust which requires handling preopens to translate "open this path" to "open this sub-path rooted from this fd", or changing open calls to openat effectively. That's all done internally by wasi-libc anyway, however, so there's not really any need for rust's standard library to duplicate all of that any more.

The main difference between wasi and unix comes down to extensions where on Unix there's all sorts of extra symbols/extensions/etc. That could be handled relatively easily internally though with #[cfg] in the unix implementation (which already has a lot of #[cfg]). Basically I'm rationalizing to myself that I believe it still makes sense for wasi to not be cfg(unix), but using the unix implementations locally within the standard library could make sense.

Lemme test out those ideas and see if I can't delete even more code here.

@alexcrichton alexcrichton marked this pull request as draft October 13, 2025 22:04
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 13, 2025
@alexcrichton
Copy link
Member Author

Ok I think that actually worked out really well -- alexcrichton@6760496 -- so I'm going to switch this PR to taking that approach. Effectively WASIp{1,2,3} will look like "unix" for operations related to the filesystem, threads, timers, etc. There's still platform differences for things like getting arguments and other bits here and there but I think those, in the limit of time, can go through libc as well.

Effectively wasi-libc has matured/changed enough to the point that I think it's more reasonable to go through that for various calls and that should reduce the size of the WASI-specific burden in the standard library. Additionally this reduces the distinction between WASIp1 and WASIp2 even further to by unifying their "pal" module into one since there's virtually no difference now. Overall this feels like a much better state of affairs to me.

This all depends on various libc changes, however, so I'll work on getting those upstream. In the meantime I'll mark this as a draft and I'll ping when this is ready for another round once libc is updated.

alexcrichton added a commit to alexcrichton/libc that referenced this pull request Oct 14, 2025
This commit fills out definitions in libc for rust-lang/rust#147572
notably filling out some fs-related functions as well as many
pthread-related functions. The pthread-related functions were not
available originally with wasi-libc but nowadays are stubs for
single-threaded behavior. The goal is to make wasi targets more "unix
like" in libstd and have less WASI-specific code.
github-merge-queue bot pushed a commit to rust-lang/libc that referenced this pull request Oct 16, 2025
This commit fills out definitions in libc for rust-lang/rust#147572
notably filling out some fs-related functions as well as many
pthread-related functions. The pthread-related functions were not
available originally with wasi-libc but nowadays are stubs for
single-threaded behavior. The goal is to make wasi targets more "unix
like" in libstd and have less WASI-specific code.
@bors
Copy link
Collaborator

bors commented Oct 18, 2025

☔ The latest upstream changes (presumably #147838) made this pull request unmergeable. Please resolve the merge conflicts.

@alexcrichton
Copy link
Member Author

I've updated this and code-wise it's where I'm pretty comfortable. This is still blocked on a libc release to get merged so I'm leaving this in draft form, but if anyone's curious to take a look and read the updated description/etc it should all be there now.

tgross35 pushed a commit to tgross35/rust-libc that referenced this pull request Nov 3, 2025
This commit fills out definitions in libc for rust-lang/rust#147572
notably filling out some fs-related functions as well as many
pthread-related functions. The pthread-related functions were not
available originally with wasi-libc but nowadays are stubs for
single-threaded behavior. The goal is to make wasi targets more "unix
like" in libstd and have less WASI-specific code.

(backport <rust-lang#4747>)
(cherry picked from commit 702efb9)
tgross35 pushed a commit to tgross35/rust-libc that referenced this pull request Nov 3, 2025
This commit fills out definitions in libc for rust-lang/rust#147572
notably filling out some fs-related functions as well as many
pthread-related functions. The pthread-related functions were not
available originally with wasi-libc but nowadays are stubs for
single-threaded behavior. The goal is to make wasi targets more "unix
like" in libstd and have less WASI-specific code.

(backport <rust-lang#4747>)
(cherry picked from commit 702efb9)
github-merge-queue bot pushed a commit to rust-lang/libc that referenced this pull request Nov 4, 2025
This commit fills out definitions in libc for rust-lang/rust#147572
notably filling out some fs-related functions as well as many
pthread-related functions. The pthread-related functions were not
available originally with wasi-libc but nowadays are stubs for
single-threaded behavior. The goal is to make wasi targets more "unix
like" in libstd and have less WASI-specific code.

(backport <#4747>)
(cherry picked from commit 702efb9)
@rustbot rustbot added the O-unix Operating system: Unix-like label Nov 14, 2025
@alexcrichton
Copy link
Member Author

alexcrichton commented Nov 14, 2025

Looks like I forgot to actually push last time... I've rebased and additionally deleted the wasip2-specific network-related module so now it also shares unix.rs for networking things. Still blocked on a libc release though

@alexcrichton alexcrichton changed the title std: Use libc for filesystem ops on WASI targets std: Use more unix.rs code on WASI targets Nov 14, 2025
@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented Nov 29, 2025

☔ The latest upstream changes (presumably #144465) made this pull request unmergeable. Please resolve the merge conflicts.

rust-timer added a commit that referenced this pull request Dec 15, 2025
Rollup merge of #149864 - alexcrichton:wasi-avoid-linkat, r=joboet

std: Don't use `linkat` on the `wasm32-wasi*` targets

This commit is a follow-up to #147572 and the issue reported at the end of that PR where the `std::fs::hard_link` function is broken after that PR landed. The true culprit and bug here is fixed in WebAssembly/wasi-libc#690 but until that's released in a wasi-sdk version it should be reasonable, on WASI, to skip the `linkat` function.
@Kobzol
Copy link
Member

Kobzol commented Dec 16, 2025

Except for the helloworld doc regression, this seems to be noise.

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Dec 16, 2025
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Dec 18, 2025
std: Don't use `linkat` on the `wasm32-wasi*` targets

This commit is a follow-up to rust-lang/rust#147572 and the issue reported at the end of that PR where the `std::fs::hard_link` function is broken after that PR landed. The true culprit and bug here is fixed in WebAssembly/wasi-libc#690 but until that's released in a wasi-sdk version it should be reasonable, on WASI, to skip the `linkat` function.
@Sytten
Copy link

Sytten commented Dec 22, 2025

This caused #150290 too, thread sleeps fails now @alexcrichton

@alexcrichton
Copy link
Member Author

Thanks for the heads up, that's fixed in #150291 and WebAssembly/wasi-libc#696

bors added a commit that referenced this pull request Dec 23, 2025
std: Use `usleep` temporarily on WASI targets

This fixes some fallout from #147572 where the `thread::sleep` function is is broken on `wasm32-wasip2` after that PR. The cause for this is a broken implementation of `nanosleep` in wasi-libc itself which is being fixed in WebAssembly/wasi-libc#696. Similar to #149864 this avoids the problematic function for now while the wasi-libc changes take some time to propagate into a wasi-sdk release.

Closes #150290
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
std: Use `usleep` temporarily on WASI targets

This fixes some fallout from rust-lang/rust#147572 where the `thread::sleep` function is is broken on `wasm32-wasip2` after that PR. The cause for this is a broken implementation of `nanosleep` in wasi-libc itself which is being fixed in WebAssembly/wasi-libc#696. Similar to rust-lang/rust#149864 this avoids the problematic function for now while the wasi-libc changes take some time to propagate into a wasi-sdk release.

Closes rust-lang/rust#150290
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Dec 24, 2025
std: Use `usleep` temporarily on WASI targets

This fixes some fallout from rust-lang/rust#147572 where the `thread::sleep` function is is broken on `wasm32-wasip2` after that PR. The cause for this is a broken implementation of `nanosleep` in wasi-libc itself which is being fixed in WebAssembly/wasi-libc#696. Similar to rust-lang/rust#149864 this avoids the problematic function for now while the wasi-libc changes take some time to propagate into a wasi-sdk release.

Closes rust-lang/rust#150290
github-actions bot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
std: Use `usleep` temporarily on WASI targets

This fixes some fallout from rust-lang/rust#147572 where the `thread::sleep` function is is broken on `wasm32-wasip2` after that PR. The cause for this is a broken implementation of `nanosleep` in wasi-libc itself which is being fixed in WebAssembly/wasi-libc#696. Similar to rust-lang/rust#149864 this avoids the problematic function for now while the wasi-libc changes take some time to propagate into a wasi-sdk release.

Closes rust-lang/rust#150290
cdmurph32 added a commit to cdmurph32/rust that referenced this pull request Jan 9, 2026
When PR rust-lang#147572 switched WASI to use Unix-style filesystem APIs, the
open_to_and_set_permissions function for WASI was implemented to call
OpenOptions::new().open() without setting any access mode flags.

This causes std::fs::copy to fail with the error:
"must specify at least one of read, write, or append access"

The fix is to explicitly set .write(true), .create(true), and
.truncate(true) on the OpenOptions, matching the behavior of the
non-WASI Unix implementation but without the permission handling
that WASI doesn't support.

Minimal reproduction:
    fn main() {
        std::fs::write("/src.txt", b"test").unwrap();
        match std::fs::copy("/src.txt", "/dst.txt") {
            Ok(_) => println!("PASS: fs::copy works!"),
            Err(e) => println!("FAIL: {}", e),
        }
    }

    # Compile and run:
    rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm
    wasmtime -S cli --dir . test.wasm

    # Before fix: FAIL: must specify at least one of read, write, or append access
    # After fix:  PASS: fs::copy works!

Note: The existing test library/std/src/fs/tests.rs::copy_file_ok
would have caught this regression if the std test suite ran on WASI
targets. Currently std tests don't compile for wasm32-wasip2 due to
Unix-specific test code in library/std/src/sys/fd/unix/tests.rs.

Fixes the regression introduced in nightly-2025-12-10.
Urgau added a commit to Urgau/rust that referenced this pull request Jan 9, 2026
Fix std::fs::copy on WASI by setting proper OpenOptions flags

When PR rust-lang#147572 switched WASI to use Unix-style filesystem APIs, the open_to_and_set_permissions function for WASI was implemented to call OpenOptions::new().open() without setting any access mode flags.

This causes std::fs::copy to fail with the error:
"must specify at least one of read, write, or append access"

The fix is to explicitly set .write(true), .create(true), and .truncate(true) on the OpenOptions, matching the behavior of the non-WASI Unix implementation but without the permission handling that WASI doesn't support.

Minimal reproduction:
```rs
    fn main() {
        std::fs::write("/src.txt", b"test").unwrap();
        match std::fs::copy("/src.txt", "/dst.txt") {
            Ok(_) => println!("PASS: fs::copy works!"),
            Err(e) => println!("FAIL: {}", e),
        }
    }
```
    # Compile and run:
    rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm
    wasmtime -S cli --dir . test.wasm

    # Before fix: FAIL: must specify at least one of read, write, or append access
    # After fix:  PASS: fs::copy works!

Note: The existing test library/std/src/fs/tests.rs::copy_file_ok would have caught this regression if the std test suite ran on WASI targets. Currently std tests don't compile for wasm32-wasip2 due to Unix-specific test code in library/std/src/sys/fd/unix/tests.rs.

Fixes the regression introduced in nightly-2025-12-10.

r? @alexcrichton
tgross35 added a commit to tgross35/rust that referenced this pull request Jan 9, 2026
Fix std::fs::copy on WASI by setting proper OpenOptions flags

When PR rust-lang#147572 switched WASI to use Unix-style filesystem APIs, the open_to_and_set_permissions function for WASI was implemented to call OpenOptions::new().open() without setting any access mode flags.

This causes std::fs::copy to fail with the error:
"must specify at least one of read, write, or append access"

The fix is to explicitly set .write(true), .create(true), and .truncate(true) on the OpenOptions, matching the behavior of the non-WASI Unix implementation but without the permission handling that WASI doesn't support.

Minimal reproduction:
```rs
    fn main() {
        std::fs::write("/src.txt", b"test").unwrap();
        match std::fs::copy("/src.txt", "/dst.txt") {
            Ok(_) => println!("PASS: fs::copy works!"),
            Err(e) => println!("FAIL: {}", e),
        }
    }
```
    # Compile and run:
    rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm
    wasmtime -S cli --dir . test.wasm

    # Before fix: FAIL: must specify at least one of read, write, or append access
    # After fix:  PASS: fs::copy works!

Note: The existing test library/std/src/fs/tests.rs::copy_file_ok would have caught this regression if the std test suite ran on WASI targets. Currently std tests don't compile for wasm32-wasip2 due to Unix-specific test code in library/std/src/sys/fd/unix/tests.rs.

Fixes the regression introduced in nightly-2025-12-10.

r? @alexcrichton
rust-timer added a commit that referenced this pull request Jan 10, 2026
Rollup merge of #150881 - fix-wasi-fs-copy, r=alexcrichton

Fix std::fs::copy on WASI by setting proper OpenOptions flags

When PR #147572 switched WASI to use Unix-style filesystem APIs, the open_to_and_set_permissions function for WASI was implemented to call OpenOptions::new().open() without setting any access mode flags.

This causes std::fs::copy to fail with the error:
"must specify at least one of read, write, or append access"

The fix is to explicitly set .write(true), .create(true), and .truncate(true) on the OpenOptions, matching the behavior of the non-WASI Unix implementation but without the permission handling that WASI doesn't support.

Minimal reproduction:
```rs
    fn main() {
        std::fs::write("/src.txt", b"test").unwrap();
        match std::fs::copy("/src.txt", "/dst.txt") {
            Ok(_) => println!("PASS: fs::copy works!"),
            Err(e) => println!("FAIL: {}", e),
        }
    }
```
    # Compile and run:
    rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm
    wasmtime -S cli --dir . test.wasm

    # Before fix: FAIL: must specify at least one of read, write, or append access
    # After fix:  PASS: fs::copy works!

Note: The existing test library/std/src/fs/tests.rs::copy_file_ok would have caught this regression if the std test suite ran on WASI targets. Currently std tests don't compile for wasm32-wasip2 due to Unix-specific test code in library/std/src/sys/fd/unix/tests.rs.

Fixes the regression introduced in nightly-2025-12-10.

r? @alexcrichton
cdmurph32 added a commit to cdmurph32/rust that referenced this pull request Jan 12, 2026
PR rust-lang#147572 changed WASI to use the Unix threading implementation, but
WASI does not support threading. When the Unix code tries to call
pthread_create, it fails with EAGAIN, causing libraries like rayon to
panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations correctly handled this:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading
for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling)
panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support
cdmurph32 added a commit to cdmurph32/rust that referenced this pull request Jan 12, 2026
PR rust-lang#147572 changed WASI to use the Unix threading implementation, but
WASI does not support threading. When the Unix code tries to call
pthread_create, it fails with EAGAIN, causing libraries like rayon to
panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading
for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling)
panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support
cdmurph32 added a commit to cdmurph32/rust that referenced this pull request Jan 12, 2026
PR rust-lang#147572 changed WASI to use the Unix threading implementation, but
WASI does not support threading. When the Unix code tries to call
pthread_create, it fails with EAGAIN, causing libraries like rayon to
panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading
for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling)
panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
fix: WASI threading regression by disabling pthread usage

PR rust-lang#147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

r? @alexcrichton
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
fix: WASI threading regression by disabling pthread usage

PR rust-lang#147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

r? @alexcrichton
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
fix: WASI threading regression by disabling pthread usage

PR rust-lang#147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

r? @alexcrichton
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
fix: WASI threading regression by disabling pthread usage

PR rust-lang#147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

r? @alexcrichton
rust-timer added a commit that referenced this pull request Jan 15, 2026
Rollup merge of #151016 - fix_wasi_threading, r=alexcrichton

fix: WASI threading regression by disabling pthread usage

PR #147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

r? @alexcrichton
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jan 15, 2026
fix: WASI threading regression by disabling pthread usage

PR rust-lang/rust#147572 changed WASI to use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool.

The old wasip1/wasip2 implementations:
- wasip1: Threading conditionally available with atomics (experimental)
- wasip2: Threading unconditionally unsupported

This fix restores that behavior by disabling pthread-based threading for all WASI targets:
1. Guard the pthread-based Thread implementation with #[cfg(not(target_os = "wasi"))]
2. Provide an unsupported stub (Thread(!)) for WASI
3. Return Err(io::Error::UNSUPPORTED_PLATFORM) when Thread::new is called

Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10.

Before fix:
  pthread_create returns EAGAIN (error code 6)
  ThreadPoolBuildError { kind: IOError(Os { code: 6,
  kind: WouldBlock, message: "Resource temporarily unavailable" }) }

After fix:
  Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM)
  Libraries can gracefully handle the lack of threading support

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

Labels

A-meta Area: Issues & PRs about the rust-lang/rust repository itself A-rustdoc-search Area: Rustdoc's search feature merged-by-bors This PR was explicitly merged by bors. O-unix Operating system: Unix-like O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants