Last active
November 5, 2023 09:46
-
-
Save b-ma/53094341fd51c1ed1ab165b840ea691b to your computer and use it in GitHub Desktop.
Struct drops itself in GC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use llq::{Node, Queue}; | |
struct AudioRenderer { | |
is_real_node: bool, | |
garbage_collector: Option<llq::Producer<Self>>, | |
garbage_node: Option<llq::Node<Self>>, | |
} | |
impl AudioRenderer { | |
fn new(garbage_collector: llq::Producer<Self>) -> Self { | |
Self { | |
is_real_node: true, | |
garbage_collector: Some(garbage_collector), | |
garbage_node: Some(Node::new(Self::tombstone())), | |
} | |
} | |
fn tombstone() -> Self { | |
Self { | |
is_real_node: false, | |
garbage_collector: None, | |
garbage_node: None, | |
} | |
} | |
} | |
impl Drop for AudioRenderer { | |
fn drop(&mut self) { | |
// should be called twice | |
println!("1. drop called in thread: {:?} - is_real_node {:?}", std::thread::current().id(), self.is_real_node); | |
// once self drop is called for the second time in GC thread, it should not pass here... | |
if self.garbage_collector.is_some() { | |
println!("- sending self to GC thread: {:?}", std::thread::current().id()); | |
let mut garbage_collector = self.garbage_collector.take().unwrap(); | |
// replace self with tombstone renderer | |
let mut holder = self.garbage_node.take().unwrap(); | |
std::mem::swap(&mut *holder, self); | |
garbage_collector.push(holder); | |
} | |
println!("2. drop called in thread: {:?} - is_real_node {:?}", std::thread::current().id(), self.is_real_node); | |
} | |
} | |
fn main() { | |
let (producer, mut consumer) = Queue::<AudioRenderer>::new().split(); | |
println!("+ main (render) thread: {:?}", std::thread::current().id()); | |
let audio_renderer = AudioRenderer::new(producer); | |
drop(audio_renderer); | |
std::thread::spawn(move || { | |
let stuff = consumer.pop().unwrap(); | |
println!("+ stuff received in GC thread {:?} - is_real_node {:?}", std::thread::current().id(), stuff.is_real_node); | |
assert!(consumer.pop().is_none()); | |
}).join().unwrap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment