focus_chain_provider/
instance_counter.rs1use std::sync::atomic::{AtomicUsize, Ordering};
6use std::sync::Arc;
7
8#[derive(Debug, Clone)]
14pub(crate) struct InstanceCounter {
15 inner: Arc<AtomicUsize>,
16}
17
18impl InstanceCounter {
19 pub fn new() -> Self {
21 Self { inner: Arc::new(0.into()) }
22 }
23
24 pub fn make_token(&self) -> CountingToken {
27 let token = CountingToken { inner: self.inner.clone() };
28 self.inner.fetch_add(1, Ordering::SeqCst);
29 token
30 }
31
32 pub fn count(&self) -> usize {
34 self.inner.load(Ordering::SeqCst)
35 }
36}
37
38#[derive(Debug)]
40pub(crate) struct CountingToken {
41 inner: Arc<AtomicUsize>,
42}
43
44impl Drop for CountingToken {
45 fn drop(&mut self) {
46 self.inner.fetch_sub(1, Ordering::SeqCst);
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::InstanceCounter;
53 #[test]
54 fn smoke_test() {
55 let counter = InstanceCounter::new();
56 assert_eq!(counter.count(), 0);
57
58 let token_a = counter.make_token();
59 assert_eq!(counter.count(), 1);
60
61 let clone = counter.clone();
62 assert_eq!(counter.count(), 1);
63 assert_eq!(clone.count(), 1);
64
65 let token_b = counter.make_token();
66 assert_eq!(counter.count(), 2);
67 assert_eq!(clone.count(), 2);
68
69 drop(clone);
70 assert_eq!(counter.count(), 2);
71
72 drop(token_a);
73 assert_eq!(counter.count(), 1);
74
75 drop(token_b);
76 assert_eq!(counter.count(), 0);
77 }
78}