1198: Fix command allocator race condition with maintenance r=kvark a=kvark

**Connections**
Fixes #1196

**Description**
This was a recent change, where I thought it would be more pure to just prepare the pool but not create anything right away. It looked more elegant, but now we see it was flowed.

**Testing**
Not really tested the concurrent aspect of it, but it should work.
Perhaps, we can hook up Loom in the future for this task?

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot]
2021-02-05 05:59:16 +00:00
committed by GitHub
2 changed files with 25 additions and 20 deletions

View File

@@ -98,26 +98,32 @@ impl<B: GfxBackend> CommandAllocator<B> {
let mut inner = self.inner.lock();
use std::collections::hash_map::Entry;
if let Entry::Vacant(e) = inner.pools.entry(thread_id) {
tracing::info!("Starting on thread {:?}", thread_id);
let raw = unsafe {
device
.create_command_pool(
self.queue_family,
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
)
.or(Err(DeviceError::OutOfMemory))?
};
e.insert(CommandPool {
raw,
total: 0,
available: Vec::new(),
pending: Vec::new(),
});
}
let pool = match inner.pools.entry(thread_id) {
Entry::Vacant(e) => {
tracing::info!("Starting on thread {:?}", thread_id);
let raw = unsafe {
device
.create_command_pool(
self.queue_family,
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
)
.or(Err(DeviceError::OutOfMemory))?
};
e.insert(CommandPool {
raw,
total: 0,
available: Vec::new(),
pending: Vec::new(),
})
}
Entry::Occupied(e) => e.into_mut(),
};
//Note: we have to allocate the first buffer right here, or otherwise
// the pool may be cleaned up by maintenance called from another thread.
Ok(CommandBuffer {
raw: Vec::new(),
raw: vec![pool.allocate()],
is_recording: true,
recorded_thread_id: thread_id,
device_id,

View File

@@ -3606,14 +3606,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
Err(e) => break e,
};
let mut raw = device.cmd_allocator.extend(&command_buffer);
let mut raw = command_buffer.raw.first_mut().unwrap();
unsafe {
if let Some(ref label) = desc.label {
device.raw.set_command_buffer_name(&mut raw, label);
}
raw.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
}
command_buffer.raw.push(raw);
let id = hub
.command_buffers