Skip to content

Commit

Permalink
Don't implement Send or Sync for Wasm types
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Apr 14, 2023
1 parent bf8e6fe commit 4549ddd
Show file tree
Hide file tree
Showing 15 changed files with 480 additions and 452 deletions.
2 changes: 2 additions & 0 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,9 @@ pub struct RenderBundle<A: HalApi> {
pub(crate) life_guard: LifeGuard,
}

#[cfg(not(target_arch = "wasm32"))]
unsafe impl<A: HalApi> Send for RenderBundle<A> {}
#[cfg(not(target_arch = "wasm32"))]
unsafe impl<A: HalApi> Sync for RenderBundle<A> {}

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

#[cfg(not(target_arch = "wasm32"))]
unsafe impl Send for SubmittedWorkDoneClosureC {}

pub struct SubmittedWorkDoneClosure {
Expand All @@ -42,17 +43,18 @@ pub struct SubmittedWorkDoneClosure {
inner: SubmittedWorkDoneClosureInner,
}

#[cfg(not(target_arch = "wasm32"))]
type SubmittedWorkDoneCallback = Box<dyn FnOnce() + Send + 'static>;
#[cfg(target_arch = "wasm32")]
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
3 changes: 3 additions & 0 deletions wgpu-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ pub fn format_pretty_any(
#[derive(Debug)]
pub struct ContextError {
pub string: &'static str,
#[cfg(not(target_arch = "wasm32"))]
pub cause: Box<dyn Error + Send + Sync + 'static>,
#[cfg(target_arch = "wasm32")]
pub cause: Box<dyn Error + 'static>,
pub label_key: &'static str,
pub label: String,
}
Expand Down
18 changes: 11 additions & 7 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ pub(crate) enum BufferMapState<A: hal::Api> {
Idle,
}

#[cfg(not(target_arch = "wasm32"))]
unsafe impl<A: hal::Api> Send for BufferMapState<A> {}
#[cfg(not(target_arch = "wasm32"))]
unsafe impl<A: hal::Api> Sync for BufferMapState<A> {}

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

#[cfg(not(target_arch = "wasm32"))]
unsafe impl Send for BufferMapCallbackC {}

pub struct BufferMapCallback {
Expand All @@ -82,17 +85,18 @@ pub struct BufferMapCallback {
inner: Option<BufferMapCallbackInner>,
}

#[cfg(not(target_arch = "wasm32"))]
type BufferMapCallbackCallback = Box<dyn FnOnce(BufferAccessResult) + Send + 'static>;
#[cfg(target_arch = "wasm32")]
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
6 changes: 0 additions & 6 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,12 +934,6 @@ impl super::AdapterShared {
}
}

// SAFE: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for super::Adapter {}
#[cfg(target_arch = "wasm32")]
unsafe impl Send for super::Adapter {}

#[cfg(test)]
mod tests {
use super::super::Adapter;
Expand Down
6 changes: 0 additions & 6 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,9 +1320,3 @@ impl crate::Device<super::Api> for super::Device {
}
}
}

// SAFE: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for super::Device {}
#[cfg(target_arch = "wasm32")]
unsafe impl Send for super::Device {}
32 changes: 2 additions & 30 deletions wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,6 @@ pub struct Buffer {
data: Option<Arc<std::sync::Mutex<Vec<u8>>>>,
}

// Safe: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for Buffer {}
#[cfg(target_arch = "wasm32")]
unsafe impl Send for Buffer {}

#[derive(Clone, Debug)]
pub enum TextureInner {
Renderbuffer {
Expand All @@ -268,12 +262,6 @@ pub enum TextureInner {
},
}

// SAFE: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Send for TextureInner {}
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for TextureInner {}

impl TextureInner {
fn as_native(&self) -> (glow::Texture, BindTarget) {
match *self {
Expand Down Expand Up @@ -462,12 +450,6 @@ struct UniformDesc {
utype: u32,
}

// Safe: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for UniformDesc {}
#[cfg(target_arch = "wasm32")]
unsafe impl Send for UniformDesc {}

/// For each texture in the pipeline layout, store the index of the only
/// sampler (in this layout) that the texture is used with.
type SamplerBindMap = [Option<u8>; MAX_TEXTURE_SLOTS];
Expand Down Expand Up @@ -530,22 +512,10 @@ 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")]
unsafe impl Sync 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")]
unsafe impl Sync for ComputePipeline {}

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

#[cfg(not(target_arch = "wasm32"))]
unsafe impl Send for Fence {}
#[cfg(not(target_arch = "wasm32"))]
unsafe impl Sync for Fence {}

impl Fence {
Expand Down
6 changes: 0 additions & 6 deletions wgpu-hal/src/gles/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1524,9 +1524,3 @@ impl crate::Queue<super::Api> for super::Queue {
1.0
}
}

// SAFE: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for super::Queue {}
#[cfg(target_arch = "wasm32")]
unsafe impl Send for super::Queue {}
8 changes: 0 additions & 8 deletions wgpu-hal/src/gles/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,6 @@ impl Instance {
}
}

// SAFE: WASM doesn't have threads
unsafe impl Sync for Instance {}
unsafe impl Send for Instance {}

impl crate::Instance<super::Api> for Instance {
unsafe fn init(_desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
Ok(Instance {
Expand Down Expand Up @@ -168,10 +164,6 @@ pub struct Surface {
srgb_present_program: Option<glow::Program>,
}

// SAFE: Because web doesn't have threads ( yet )
unsafe impl Sync for Surface {}
unsafe impl Send for Surface {}

#[derive(Clone, Debug)]
pub struct Swapchain {
pub(crate) extent: wgt::Extent3d,
Expand Down
62 changes: 42 additions & 20 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,25 +161,25 @@ pub trait Api: Clone + Sized {

type Queue: Queue<Self>;
type CommandEncoder: CommandEncoder<Self>;
type CommandBuffer: Send + Sync + fmt::Debug;
type CommandBuffer: MaybeSend + MaybeSync + fmt::Debug;

type Buffer: fmt::Debug + Send + Sync + 'static;
type Texture: fmt::Debug + Send + Sync + 'static;
type SurfaceTexture: fmt::Debug + Send + Sync + Borrow<Self::Texture>;
type TextureView: fmt::Debug + Send + Sync;
type Sampler: fmt::Debug + Send + Sync;
type QuerySet: fmt::Debug + Send + Sync;
type Fence: fmt::Debug + Send + Sync;
type Buffer: fmt::Debug + MaybeSend + MaybeSync + 'static;
type Texture: fmt::Debug + MaybeSend + MaybeSync + 'static;
type SurfaceTexture: fmt::Debug + MaybeSend + MaybeSync + Borrow<Self::Texture>;
type TextureView: fmt::Debug + MaybeSend + MaybeSync;
type Sampler: fmt::Debug + MaybeSend + MaybeSync;
type QuerySet: fmt::Debug + MaybeSend + MaybeSync;
type Fence: fmt::Debug + MaybeSend + MaybeSync;

type BindGroupLayout: Send + Sync;
type BindGroup: fmt::Debug + Send + Sync;
type PipelineLayout: Send + Sync;
type ShaderModule: fmt::Debug + Send + Sync;
type RenderPipeline: Send + Sync;
type ComputePipeline: Send + Sync;
type BindGroupLayout: MaybeSend + MaybeSync;
type BindGroup: fmt::Debug + MaybeSend + MaybeSync;
type PipelineLayout: MaybeSend + MaybeSync;
type ShaderModule: fmt::Debug + MaybeSend + MaybeSync;
type RenderPipeline: MaybeSend + MaybeSync;
type ComputePipeline: MaybeSend + MaybeSync;
}

pub trait Instance<A: Api>: Sized + Send + Sync {
pub trait Instance<A: Api>: Sized + MaybeSend + MaybeSync {
unsafe fn init(desc: &InstanceDescriptor) -> Result<Self, InstanceError>;
unsafe fn create_surface(
&self,
Expand All @@ -190,7 +190,7 @@ pub trait Instance<A: Api>: Sized + Send + Sync {
unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<A>>;
}

pub trait Surface<A: Api>: Send + Sync {
pub trait Surface<A: Api>: MaybeSend + MaybeSync {
unsafe fn configure(
&mut self,
device: &A::Device,
Expand All @@ -216,7 +216,7 @@ pub trait Surface<A: Api>: Send + Sync {
unsafe fn discard_texture(&mut self, texture: A::SurfaceTexture);
}

pub trait Adapter<A: Api>: Send + Sync {
pub trait Adapter<A: Api>: MaybeSend + MaybeSync {
unsafe fn open(
&self,
features: wgt::Features,
Expand All @@ -240,7 +240,7 @@ pub trait Adapter<A: Api>: Send + Sync {
unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp;
}

pub trait Device<A: Api>: Send + Sync {
pub trait Device<A: Api>: MaybeSend + MaybeSync {
/// Exit connection to this logical device.
unsafe fn exit(self, queue: A::Queue);
/// Creates a new buffer.
Expand Down Expand Up @@ -336,7 +336,7 @@ pub trait Device<A: Api>: Send + Sync {
unsafe fn stop_capture(&self);
}

pub trait Queue<A: Api>: Send + Sync {
pub trait Queue<A: Api>: MaybeSend + MaybeSync {
/// Submits the command buffers for execution on GPU.
///
/// Valid usage:
Expand All @@ -360,7 +360,7 @@ pub trait Queue<A: Api>: Send + Sync {
/// Serves as a parent for all the encoded command buffers.
/// Works in bursts of action: one or more command buffers are recorded,
/// then submitted to a queue, and then it needs to be `reset_all()`.
pub trait CommandEncoder<A: Api>: Send + Sync + fmt::Debug {
pub trait CommandEncoder<A: Api>: MaybeSend + MaybeSync + fmt::Debug {
/// Begin encoding a new command buffer.
unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>;
/// Discard currently recorded list, if any.
Expand Down Expand Up @@ -1309,6 +1309,28 @@ impl ValidationCanary {
}
}

use send_sync::*;

mod send_sync {
#[cfg(not(target_arch = "wasm32"))]
pub trait MaybeSend: Send {}
#[cfg(not(target_arch = "wasm32"))]
impl<T: Send> MaybeSend for T {}
#[cfg(target_arch = "wasm32")]
pub trait MaybeSend {}
#[cfg(target_arch = "wasm32")]
impl<T> MaybeSend for T {}

#[cfg(not(target_arch = "wasm32"))]
pub trait MaybeSync: Sync {}
#[cfg(not(target_arch = "wasm32"))]
impl<T: Sync> MaybeSync for T {}
#[cfg(target_arch = "wasm32")]
pub trait MaybeSync {}
#[cfg(target_arch = "wasm32")]
impl<T> MaybeSync for T {}
}

#[test]
fn test_default_limits() {
let limits = wgt::Limits::default();
Expand Down
5 changes: 0 additions & 5 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5765,11 +5765,6 @@ impl std::ops::Deref for ExternalImageSource {
}
}

#[cfg(target_arch = "wasm32")]
unsafe impl Send for ExternalImageSource {}
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for ExternalImageSource {}

/// Color spaces supported on the web.
///
/// Corresponds to [HTML Canvas `PredefinedColorSpace`](
Expand Down
Loading

0 comments on commit 4549ddd

Please sign in to comment.