mirror of https://gitlab.freedesktop.org/mesa/mesa
event: break long dependency chains on drop
This prevents stack overflows on drop without making it expensive to read from dependencies (e.g. my attempt to use Weak instead). Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29190>
This commit is contained in:
parent
2f1f98e846
commit
48c752d3e0
|
@ -10,6 +10,7 @@ use mesa_rust_util::static_assert;
|
|||
use rusticl_opencl_gen::*;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Condvar;
|
||||
use std::sync::Mutex;
|
||||
|
@ -262,6 +263,27 @@ impl Event {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for Event {
|
||||
// implement drop in order to prevent stack overflows of long dependency chains.
|
||||
//
|
||||
// This abuses the fact that `Arc::into_inner` only succeeds when there is one strong reference
|
||||
// so we turn a recursive drop chain into a drop list for events having no other references.
|
||||
fn drop(&mut self) {
|
||||
if self.deps.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut deps_list = vec![mem::take(&mut self.deps)];
|
||||
while let Some(deps) = deps_list.pop() {
|
||||
for dep in deps {
|
||||
if let Some(mut dep) = Arc::into_inner(dep) {
|
||||
deps_list.push(mem::take(&mut dep.deps));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO worker thread per device
|
||||
// Condvar to wait on new events to work on
|
||||
// notify condvar when flushing queue events to worker
|
||||
|
|
Loading…
Reference in New Issue