[core] Use ManuallyDrop for wgpu_core::device::Queue::raw.

Change the field `wgpu_core::device::Queue::raw` from an
`Option<A::Queue>` to a `std::mem::ManuallyDrop<A::Queue>`. Replace
various `.as_ref().unwrap()` chains with calls to a new accessor
function `Queue::raw`.

An `Option` is misleading, as this field is always populated during
the lifetime of a `Queue`. Instead, we simply have a field whose value
needs to be moved in `<Queue as Drop>::drop`; `ManuallyDrop` is the
Rust idiom for this situation.
This commit is contained in:
Jim Blandy 2024-07-22 13:15:37 -07:00
parent 34d492a647
commit ebb011fc6b
4 changed files with 25 additions and 25 deletions

View File

@ -30,7 +30,7 @@ use smallvec::SmallVec;
use std::{
iter,
mem::{self},
mem::{self, ManuallyDrop},
ptr::NonNull,
sync::{atomic::Ordering, Arc},
};
@ -39,10 +39,23 @@ use thiserror::Error;
use super::Device;
pub struct Queue<A: HalApi> {
pub(crate) raw: Option<A::Queue>,
raw: ManuallyDrop<A::Queue>,
pub(crate) device: Arc<Device<A>>,
}
impl<A: HalApi> Queue<A> {
pub(crate) fn new(device: Arc<Device<A>>, raw: A::Queue) -> Self {
Queue {
raw: ManuallyDrop::new(raw),
device,
}
}
pub(crate) fn raw(&self) -> &A::Queue {
&self.raw
}
}
crate::impl_resource_type!(Queue);
// TODO: https://github.com/gfx-rs/wgpu/issues/4014
impl<A: HalApi> Labeled for Queue<A> {
@ -56,7 +69,8 @@ crate::impl_storage_item!(Queue);
impl<A: HalApi> Drop for Queue<A> {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
let queue = self.raw.take().unwrap();
// SAFETY: we never access `self.raw` beyond this point.
let queue = unsafe { std::mem::ManuallyDrop::take(&mut self.raw) };
self.device.release_queue(queue);
}
}
@ -1272,11 +1286,9 @@ impl Global {
}
}
if let Some(pending_execution) = pending_writes.pre_submit(
&device.command_allocator,
device.raw(),
queue.raw.as_ref().unwrap(),
)? {
if let Some(pending_execution) =
pending_writes.pre_submit(&device.command_allocator, device.raw(), queue.raw())?
{
active_executions.insert(0, pending_execution);
}
@ -1298,9 +1310,7 @@ impl Global {
unsafe {
queue
.raw
.as_ref()
.unwrap()
.raw()
.submit(
&hal_command_buffers,
&submit_surface_textures,
@ -1356,7 +1366,7 @@ impl Global {
) -> Result<f32, InvalidQueue> {
let hub = A::hub(self);
match hub.queues.get(queue_id) {
Ok(queue) => Ok(unsafe { queue.raw.as_ref().unwrap().get_timestamp_period() }),
Ok(queue) => Ok(unsafe { queue.raw().get_timestamp_period() }),
Err(_) => Err(InvalidQueue),
}
}

View File

@ -1601,7 +1601,7 @@ impl<A: HalApi> Device<A> {
let encoder = self
.command_allocator
.acquire_encoder(self.raw(), queue.raw.as_ref().unwrap())?;
.acquire_encoder(self.raw(), queue.raw())?;
Ok(command::CommandBuffer::new(
encoder,

View File

@ -293,11 +293,7 @@ impl<A: HalApi> Adapter<A> {
instance_flags,
) {
let device = Arc::new(device);
let queue = Queue {
device: device.clone(),
raw: Some(hal_device.queue),
};
let queue = Arc::new(queue);
let queue = Arc::new(Queue::new(device.clone(), hal_device.queue));
device.set_queue(&queue);
return Ok((device, queue));
}

View File

@ -326,13 +326,7 @@ impl Global {
log::error!("Presented frame is from a different surface");
Err(hal::SurfaceError::Lost)
} else {
unsafe {
queue
.raw
.as_ref()
.unwrap()
.present(suf.unwrap(), raw.take().unwrap())
}
unsafe { queue.raw().present(suf.unwrap(), raw.take().unwrap()) }
}
}
_ => unreachable!(),