From 543a6913e869442675b59652348e1d6862f53fa8 Mon Sep 17 00:00:00 2001 From: Jiangfeng Huang Date: Sun, 19 Oct 2025 19:54:54 +0800 Subject: [PATCH] fix(runtime): use `Weak` to break reference cycle --- compio-runtime/src/runtime/mod.rs | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/compio-runtime/src/runtime/mod.rs b/compio-runtime/src/runtime/mod.rs index ea383dcb..30517d0c 100644 --- a/compio-runtime/src/runtime/mod.rs +++ b/compio-runtime/src/runtime/mod.rs @@ -202,11 +202,19 @@ impl Runtime { /// /// The caller should ensure the captured lifetime long enough. pub unsafe fn spawn_unchecked(&self, future: F) -> Task { - let runnables = self.runnables.clone(); - let handle = self.driver.borrow().handle(); - let schedule = move |runnable| { - runnables.schedule(runnable, &handle); + let schedule = { + // Use `Weak` to break reference cycle. + // `RunnableQueue` -> `Runnable` -> `RunnableQueue` + let runnables = Arc::downgrade(&self.runnables); + let handle = self.driver.borrow().handle(); + + move |runnable| { + if let Some(runnables) = runnables.upgrade() { + runnables.schedule(runnable, &handle); + } + } }; + let (runnable, task) = async_task::spawn_unchecked(future, schedule); runnable.schedule(); task @@ -418,21 +426,6 @@ impl Runtime { } } -impl Drop for Runtime { - fn drop(&mut self) { - self.enter(|| { - while self.runnables.sync_runnables.pop().is_some() {} - let local_runnables = unsafe { self.runnables.local_runnables.get_unchecked() }; - loop { - let runnable = local_runnables.borrow_mut().pop_front(); - if runnable.is_none() { - break; - } - } - }) - } -} - impl AsRawFd for Runtime { fn as_raw_fd(&self) -> RawFd { self.driver.borrow().as_raw_fd()