Crates.io | ferris-gc |
lib.rs | ferris-gc |
version | 0.1.5 |
source | src |
created_at | 2020-05-11 20:09:06.031887 |
updated_at | 2020-05-14 11:28:45.703908 |
description | Flexible implementation of garbage collector for Rust |
homepage | |
repository | https://github.com/redradist/ferris-gc |
max_upload_size | |
id | 240285 |
size | 55,047 |
Complete reimplementation of https://github.com/Manishearth/rust-gc from scratch providing just compatible interface
One of the main difference is a thread safe Garbage Collector implementation as well as Thread Local Garbage Collector
Here is the simple example of using FerrisGC:
use ferris_gc::{Gc, Trace, Finalize, GcCell, ferris_gc_main, ApplicationCleanup, GcOpt};
use ferris_gc::sync::Gc as GlobalGc;
use ferris_gc::sync::GcCell as GlobalGcCell;
use core::time;
use std::thread;
use std::time::Duration;
use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::Write;
#[derive(Trace)]
struct MyStruct {
jh: u32,
}
impl Drop for MyStruct {
fn drop(&mut self) {
println!("MyStruct in drop !!");
}
}
impl Finalize for MyStruct {
fn finalize(&self) {
println!("MyStruct in finalize !!");
let mut file = File::create("foo.txt");
match file {
Ok(mut f) => { f.write_all(b"Hello, world!") },
Err(e) => { Err(e) },
};
}
}
struct MyStruct3 {
jh: u32,
}
#[derive(Trace, Finalize)]
struct MyStruct39(#[unsafe_ignore_trace] MyStruct3, u16);
#[derive(Trace)]
struct MyStruct2 {
jh: Gc<u32>,
}
#[derive(Trace, Finalize)]
struct MyStructStd {
jh: GcOpt<u32>, // The same as Option<Gc<u32>>
jh2: Box<&'static str>,
jh3: Option<Box<&'static str>>,
jh4: GcOpt<Box<&'static str>>, // The same as Option<Gc<Box<&'static str>>>
jh5: Gc<Option<Box<&'static str>>>,
}
impl Drop for MyStruct2 {
fn drop(&mut self) {
println!("MyStruct in drop !!");
}
}
impl Finalize for MyStruct2 {
fn finalize(&self) {
let mut file = File::create("foo2.txt");
match file {
Ok(mut f) => { f.write_all(b"Hello, world!") },
Err(e) => { Err(e) },
};
}
}
#[ferris_gc_main]
fn main() {
{
let gc = Gc::new(2);
let gc1 = Gc::new(MyStruct { jh: 3 });
let gc2 = GcCell::new(MyStruct { jh: 3 });
gc2.borrow_mut().jh = 2;
let gc3 = Gc::new(MyStruct2 { jh: gc.clone() });
}
{
let gc1 = Gc::new(MyStruct { jh: 3 });
let gc2 = GlobalGc::new(MyStruct { jh: 3 });
thread::spawn(move || {
println!("gc2.jh is {}", gc2.jh);
});
}
let gc3 = Gc::new(MyStruct { jh: 3 });
let ten_secs = time::Duration::from_secs(5);
thread::sleep(ten_secs);
println!("Hello, GC World !!");
}
Lets try to understand step-by-step what is what here:
#[derive(Trace, Finalize)]
Macro that implements Trace and Finalize for the particular object.
It is needed because Gc::new
and GcCell::new
waiting object that implement trait Trace
and using this trait GarbageCollector is able to collect unreachable objects ...
Trait Finalize
will be called when object is disposed. Also you can implement custom trait Finalize
for your particular needs
#[ferris_gc_main]
Macro for main function in your program is needed for disposing all objects after Application finished.
It is useful because otherwise object gc3
will not be disposed by GarbageCollector and finalize will not be called ...
To add dependencies you should add:
[dependencies]
ferris-gc = { version = "0.1.5", features = ["proc-macro"] }