mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-19 18:33:30 +00:00
Fix Buffer Mapping Deadlock (#5518)
This commit is contained in:
parent
1735968969
commit
152fd0930a
@ -808,29 +808,33 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
*buffer.map_state.lock() = resource::BufferMapState::Idle;
|
||||
log::trace!("Buffer ready to map {tracker_index:?} is not tracked anymore");
|
||||
} else {
|
||||
let mapping = match std::mem::replace(
|
||||
// This _cannot_ be inlined into the match. If it is, the lock will be held
|
||||
// open through the whole match, resulting in a deadlock when we try to re-lock
|
||||
// the buffer back to active.
|
||||
let mapping = std::mem::replace(
|
||||
&mut *buffer.map_state.lock(),
|
||||
resource::BufferMapState::Idle,
|
||||
) {
|
||||
);
|
||||
let pending_mapping = match mapping {
|
||||
resource::BufferMapState::Waiting(pending_mapping) => pending_mapping,
|
||||
// Mapping cancelled
|
||||
resource::BufferMapState::Idle => continue,
|
||||
// Mapping queued at least twice by map -> unmap -> map
|
||||
// and was already successfully mapped below
|
||||
active @ resource::BufferMapState::Active { .. } => {
|
||||
*buffer.map_state.lock() = active;
|
||||
resource::BufferMapState::Active { .. } => {
|
||||
*buffer.map_state.lock() = mapping;
|
||||
continue;
|
||||
}
|
||||
_ => panic!("No pending mapping."),
|
||||
};
|
||||
let status = if mapping.range.start != mapping.range.end {
|
||||
let status = if pending_mapping.range.start != pending_mapping.range.end {
|
||||
log::debug!("Buffer {tracker_index:?} map state -> Active");
|
||||
let host = mapping.op.host;
|
||||
let size = mapping.range.end - mapping.range.start;
|
||||
let host = pending_mapping.op.host;
|
||||
let size = pending_mapping.range.end - pending_mapping.range.start;
|
||||
match super::map_buffer(
|
||||
raw,
|
||||
&buffer,
|
||||
mapping.range.start,
|
||||
pending_mapping.range.start,
|
||||
size,
|
||||
host,
|
||||
snatch_guard,
|
||||
@ -838,7 +842,8 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
Ok(ptr) => {
|
||||
*buffer.map_state.lock() = resource::BufferMapState::Active {
|
||||
ptr,
|
||||
range: mapping.range.start..mapping.range.start + size,
|
||||
range: pending_mapping.range.start
|
||||
..pending_mapping.range.start + size,
|
||||
host,
|
||||
};
|
||||
Ok(())
|
||||
@ -851,12 +856,12 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
} else {
|
||||
*buffer.map_state.lock() = resource::BufferMapState::Active {
|
||||
ptr: std::ptr::NonNull::dangling(),
|
||||
range: mapping.range,
|
||||
host: mapping.op.host,
|
||||
range: pending_mapping.range,
|
||||
host: pending_mapping.op.host,
|
||||
};
|
||||
Ok(())
|
||||
};
|
||||
pending_callbacks.push((mapping.op, status));
|
||||
pending_callbacks.push((pending_mapping.op, status));
|
||||
}
|
||||
}
|
||||
pending_callbacks
|
||||
|
Loading…
Reference in New Issue
Block a user