Skip to content

Commit

Permalink
Don't implement Send or Sync on Wasm (#3691)
Browse files Browse the repository at this point in the history
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
  • Loading branch information
daxpedda and cwfitzgerald committed Jun 29, 2023
1 parent 7c34cc8 commit 88f18ed
Show file tree
Hide file tree
Showing 22 changed files with 908 additions and 138 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ jobs:
set -e
# build for WebGPU
cargo clippy --target ${{ matrix.target }} --tests --features glsl,spirv,fragile-send-sync-non-atomic-wasm
cargo clippy --target ${{ matrix.target }} --tests --features glsl,spirv
cargo doc --target ${{ matrix.target }} --no-deps --features glsl,spirv
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Bottom level categories:
- Document feature requirements for `DEPTH32FLOAT_STENCIL8` by @ErichDonGubler in [#3734](https://github.com/gfx-rs/wgpu/pull/3734).
- Flesh out docs. for `AdapterInfo::{device,vendor}` by @ErichDonGubler in [#3763](https://github.com/gfx-rs/wgpu/pull/3763).
- Spell out which sizes are in bytes. By @jimblandy in [#3773](https://github.com/gfx-rs/wgpu/pull/3773).
- On Web, types don't implement `Send` or `Sync` anymore. By @daxpedda in [#3691](https://github.com/gfx-rs/wgpu/pull/3691)

### Bug Fixes

Expand Down
2 changes: 2 additions & 0 deletions wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ serial-pass = ["serde", "wgt/serde", "arrayvec/serde"]
id32 = []
# Enable `ShaderModuleSource::Wgsl`
wgsl = ["naga/wgsl-in"]
# Implement `Send` and `Sync` on Wasm.
fragile-send-sync-non-atomic-wasm = ["hal/fragile-send-sync-non-atomic-wasm", "wgt/fragile-send-sync-non-atomic-wasm"]

[dependencies]
arrayvec = "0.7"
Expand Down
14 changes: 14 additions & 0 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,21 @@ pub struct RenderBundle<A: HalApi> {
pub(crate) life_guard: LifeGuard,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl<A: HalApi> Send for RenderBundle<A> {}
#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl<A: HalApi> Sync for RenderBundle<A> {}

impl<A: HalApi> RenderBundle<A> {
Expand Down
34 changes: 27 additions & 7 deletions wgpu-core/src/device/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ pub struct SubmittedWorkDoneClosureC {
pub user_data: *mut u8,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl Send for SubmittedWorkDoneClosureC {}

pub struct SubmittedWorkDoneClosure {
Expand All @@ -45,17 +52,30 @@ pub struct SubmittedWorkDoneClosure {
inner: SubmittedWorkDoneClosureInner,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
type SubmittedWorkDoneCallback = Box<dyn FnOnce() + Send + 'static>;
#[cfg(not(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
)))]
type SubmittedWorkDoneCallback = Box<dyn FnOnce() + 'static>;

enum SubmittedWorkDoneClosureInner {
Rust {
callback: Box<dyn FnOnce() + Send + 'static>,
},
C {
inner: SubmittedWorkDoneClosureC,
},
Rust { callback: SubmittedWorkDoneCallback },
C { inner: SubmittedWorkDoneClosureC },
}

impl SubmittedWorkDoneClosure {
pub fn from_rust(callback: Box<dyn FnOnce() + Send + 'static>) -> Self {
pub fn from_rust(callback: SubmittedWorkDoneCallback) -> Self {
Self {
inner: SubmittedWorkDoneClosureInner::Rust { callback },
}
Expand Down
15 changes: 15 additions & 0 deletions wgpu-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,22 @@ pub fn format_pretty_any(
#[derive(Debug)]
pub struct ContextError {
pub string: &'static str,
#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
pub cause: Box<dyn Error + Send + Sync + 'static>,
#[cfg(not(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
)))]
pub cause: Box<dyn Error + 'static>,
pub label_key: &'static str,
pub label: String,
}
Expand Down
11 changes: 10 additions & 1 deletion wgpu-core/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,16 @@ impl<G: GlobalIdentityHandlerFactory> Drop for Global<G> {
}
}

#[cfg(test)]
#[cfg(all(
test,
any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
)
))]
fn _test_send_sync(global: &Global<crate::identity::IdentityManagerFactory>) {
fn test_internal<T: Send + Sync>(_: T) {}
test_internal(global)
Expand Down
48 changes: 41 additions & 7 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,21 @@ pub(crate) enum BufferMapState<A: hal::Api> {
Idle,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl<A: hal::Api> Send for BufferMapState<A> {}
#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl<A: hal::Api> Sync for BufferMapState<A> {}

#[repr(C)]
Expand All @@ -88,6 +102,13 @@ pub struct BufferMapCallbackC {
pub user_data: *mut u8,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl Send for BufferMapCallbackC {}

pub struct BufferMapCallback {
Expand All @@ -96,17 +117,30 @@ pub struct BufferMapCallback {
inner: Option<BufferMapCallbackInner>,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
type BufferMapCallbackCallback = Box<dyn FnOnce(BufferAccessResult) + Send + 'static>;
#[cfg(not(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
)))]
type BufferMapCallbackCallback = Box<dyn FnOnce(BufferAccessResult) + 'static>;

enum BufferMapCallbackInner {
Rust {
callback: Box<dyn FnOnce(BufferAccessResult) + Send + 'static>,
},
C {
inner: BufferMapCallbackC,
},
Rust { callback: BufferMapCallbackCallback },
C { inner: BufferMapCallbackC },
}

impl BufferMapCallback {
pub fn from_rust(callback: Box<dyn FnOnce(BufferAccessResult) + Send + 'static>) -> Self {
pub fn from_rust(callback: BufferMapCallbackCallback) -> Self {
Self {
inner: Some(BufferMapCallbackInner::Rust { callback }),
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dx12 = ["naga/hlsl-out", "d3d12", "bit-set", "range-alloc", "winapi/std", "winap
windows_rs = ["gpu-allocator"]
dxc_shader_compiler = ["hassle-rs"]
renderdoc = ["libloading", "renderdoc-sys"]
fragile-send-sync-non-atomic-wasm = ["wgt/fragile-send-sync-non-atomic-wasm"]
link = ["metal/link"]

[[example]]
Expand Down
13 changes: 10 additions & 3 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,10 +936,17 @@ impl super::AdapterShared {
}
}

// SAFE: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for super::Adapter {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for super::Adapter {}

#[cfg(test)]
Expand Down
13 changes: 10 additions & 3 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1321,8 +1321,15 @@ impl crate::Device<super::Api> for super::Device {
}
}

// SAFE: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for super::Device {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for super::Device {}
85 changes: 67 additions & 18 deletions wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,17 @@ pub struct Buffer {
data: Option<Arc<std::sync::Mutex<Vec<u8>>>>,
}

// Safe: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for Buffer {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for Buffer {}

#[derive(Clone, Debug)]
Expand All @@ -268,11 +275,18 @@ pub enum TextureInner {
},
}

// SAFE: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Send for TextureInner {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for TextureInner {}
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for TextureInner {}

impl TextureInner {
fn as_native(&self) -> (glow::Texture, BindTarget) {
Expand Down Expand Up @@ -462,10 +476,17 @@ struct UniformDesc {
utype: u32,
}

// Safe: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for UniformDesc {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for UniformDesc {}

/// For each texture in the pipeline layout, store the index of the only
Expand Down Expand Up @@ -530,21 +551,35 @@ pub struct RenderPipeline {
alpha_to_coverage_enabled: bool,
}

// SAFE: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Send for RenderPipeline {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for RenderPipeline {}
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for RenderPipeline {}

pub struct ComputePipeline {
inner: Arc<PipelineInner>,
}

// SAFE: Wasm doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Send for ComputePipeline {}
#[cfg(target_arch = "wasm32")]
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Sync for ComputePipeline {}
#[cfg(all(
target_arch = "wasm32",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for ComputePipeline {}

#[derive(Debug)]
pub struct QuerySet {
Expand All @@ -558,7 +593,21 @@ pub struct Fence {
pending: Vec<(crate::FenceValue, glow::Fence)>,
}

#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl Send for Fence {}
#[cfg(any(
not(target_arch = "wasm32"),
all(
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
)
))]
unsafe impl Sync for Fence {}

impl Fence {
Expand Down

0 comments on commit 88f18ed

Please sign in to comment.