diff --git a/src/lib.rs b/src/lib.rs index 4f4c108..f8745a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,9 @@ pub fn collect_cycles() { return; } - collect(state); + let _ = POSSIBLE_CYCLES.try_with(|pc| { + collect(state, pc); + }); #[cfg(feature = "auto-collect")] adjust_trigger_point(state); @@ -51,7 +53,10 @@ pub fn collect_cycles() { pub(crate) fn trigger_collection() { let _ = try_state(|state| { if !state.is_collecting() && config::config(|config| config.should_collect(state)).unwrap_or(false) { - collect(state); + let _ = POSSIBLE_CYCLES.try_with(|pc| { + collect(state, pc); + }); + adjust_trigger_point(state); } }); @@ -62,7 +67,7 @@ fn adjust_trigger_point(state: &State) { let _ = config::config(|config| config.adjust(state)); } -fn collect(state: &State) { +fn collect(state: &State, possible_cycles: &RefCell) { state.set_collecting(true); state.increment_executions_count(); @@ -80,23 +85,23 @@ fn collect(state: &State) { let _drop_guard = DropGuard { state }; #[cfg(feature = "finalization")] - while let Ok(false) = POSSIBLE_CYCLES.try_with(|pc| pc.borrow().is_empty()) { - __collect(state); + while !is_empty(possible_cycles) { + __collect(state, possible_cycles); } #[cfg(not(feature = "finalization"))] - if let Ok(false) = POSSIBLE_CYCLES.try_with(|pc| pc.borrow().is_empty()) { - __collect(state); + if !is_empty(possible_cycles) { + __collect(state, possible_cycles); } // _drop_guard is dropped here, setting state.collecting to false } -fn __collect(state: &State) { +fn __collect(state: &State, possible_cycles: &RefCell) { let mut non_root_list = List::new(); { let mut root_list = List::new(); - while let Some(ptr) = POSSIBLE_CYCLES.with(|pc| pc.borrow_mut().remove_first()) { + while let Some(ptr) = get_and_remove_first(possible_cycles) { // remove_first already marks ptr as NonMarked trace_counting(ptr, &mut root_list, &mut non_root_list); } @@ -157,6 +162,16 @@ fn __collect(state: &State) { } } +#[inline] +fn is_empty(list: &RefCell) -> bool { + list.borrow().is_empty() +} + +#[inline] +fn get_and_remove_first(list: &RefCell) -> Option>> { + list.borrow_mut().remove_first() +} + #[inline] fn deallocate_list(to_deallocate_list: List, state: &State) { let _dropping_guard = replace_state_field!(dropping, true, state);