diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 0a816b614d..139fa8f858 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -2000,8 +2000,10 @@ pub extern "C" fn wgpu_device_create_swap_chain( #[no_mangle] pub extern "C" fn wgpu_device_poll(device_id: DeviceId, force_wait: bool) { - let (device_guard, mut token) = HUB.devices.read(&mut Token::root()); - let callbacks = device_guard[device_id].maintain(force_wait, &mut token); + let callbacks = { + let (device_guard, mut token) = HUB.devices.read(&mut Token::root()); + device_guard[device_id].maintain(force_wait, &mut token) + }; Device::fire_map_callbacks(callbacks); } diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs index 92b8f820a2..ab2616ffd2 100644 --- a/wgpu-native/src/hub.rs +++ b/wgpu-native/src/hub.rs @@ -198,8 +198,9 @@ impl Access for TextureHandle {} impl Access for Root {} impl Access for TextureViewHandle {} +#[cfg(debug_assertions)] thread_local! { - static ACTIVE_TOKEN: Cell = Cell::new(false); + static ACTIVE_TOKEN: Cell = Cell::new(0); } /// A permission token to lock resource `T` or anything after it, @@ -209,38 +210,42 @@ thread_local! { /// at a time, which is enforced by `ACTIVE_TOKEN`. pub struct Token<'a, T: 'a> { level: PhantomData<&'a T>, - is_root: bool, } impl<'a, T> Token<'a, T> { fn new() -> Self { + #[cfg(debug_assertions)] + ACTIVE_TOKEN.with(|active| { + let old = active.get(); + assert_ne!(old, 0, "Root token was dropped"); + active.set(old + 1); + }); Token { level: PhantomData, - is_root: false, } } } impl Token<'static, Root> { pub fn root() -> Self { + #[cfg(debug_assertions)] ACTIVE_TOKEN.with(|active| { - assert!(!active.replace(true)); + assert_eq!(0, active.replace(1), "Root token is already active"); }); Token { level: PhantomData, - is_root: true, } } } impl<'a, T> Drop for Token<'a, T> { fn drop(&mut self) { - if self.is_root { - ACTIVE_TOKEN.with(|active| { - assert!(active.replace(false)); - }); - } + #[cfg(debug_assertions)] + ACTIVE_TOKEN.with(|active| { + let old = active.get(); + active.set(old - 1); + }); } }