1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use std::sync::{RwLock, Once}; use crate::gc::LocalGarbageCollector; use crate::gc::sync::GlobalGarbageCollector; use std::{thread, time}; use std::thread::JoinHandle; use std::sync::atomic::{AtomicBool, Ordering}; lazy_static! { pub static ref BASIC_STRATEGY_LOCAL_GCS: RwLock<Vec<&'static LocalGarbageCollector>> = { RwLock::new(Vec::new()) }; pub static ref BASIC_STRATEGY_GLOBAL_GC: RwLock<Option<&'static GlobalGarbageCollector>> = { RwLock::new(None) }; pub static ref APPLICATION_ACTIVE: AtomicBool = { AtomicBool::new(true) }; pub static ref BACKGROUND_THREADS: RwLock<Vec<JoinHandle<()>>> = { RwLock::new(Vec::new()) }; } static START_BASIC_GC_STRATEGY: Once = Once::new(); pub struct ApplicationCleanup; impl Drop for ApplicationCleanup { fn drop(&mut self) { let app_active = &(*APPLICATION_ACTIVE); app_active.store(false, Ordering::Release); let mut bthreads = (&*BACKGROUND_THREADS).write().unwrap(); while (*bthreads).len() > 0 { let bthread = (*bthreads).pop().unwrap(); bthread.join(); } } } pub fn basic_gc_strategy_start() { START_BASIC_GC_STRATEGY.call_once(|| { let bthreads = &(*BACKGROUND_THREADS); bthreads.write().unwrap().push( thread::spawn(move || { let app_active = &(*APPLICATION_ACTIVE); while app_active.load(Ordering::Acquire) { let ten_secs = time::Duration::from_millis(500); thread::sleep(ten_secs); { if let Some(global_gc) = *(*BASIC_STRATEGY_GLOBAL_GC).read().unwrap() { unsafe { global_gc.collect(); } } } { let local_gcs_read_guard = (*BASIC_STRATEGY_LOCAL_GCS).read().unwrap(); let local_gcs = &(*local_gcs_read_guard); unsafe { for local_gc in local_gcs.into_iter() { local_gc.collect(); } } } } if let Some(global_gc) = *(*BASIC_STRATEGY_GLOBAL_GC).read().unwrap() { unsafe { global_gc.collect(); } } let local_gcs_read_guard = (*BASIC_STRATEGY_LOCAL_GCS).read().unwrap(); let local_gcs = &(*local_gcs_read_guard); unsafe { for local_gc in local_gcs.into_iter() { local_gc.collect(); } } }) ); }); }