diff --git a/src/gallium/frontends/rusticl/core/event.rs b/src/gallium/frontends/rusticl/core/event.rs index cc14ec6dd080f..040b2ad58f740 100644 --- a/src/gallium/frontends/rusticl/core/event.rs +++ b/src/gallium/frontends/rusticl/core/event.rs @@ -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