From 01971b5048e5fe28335a4a402320113c0ff1f2a6 Mon Sep 17 00:00:00 2001 From: Nova Date: Sun, 12 Jun 2022 00:51:12 -0400 Subject: [PATCH] refactor(registry): use globals instead of storing in event loop --- Cargo.toml | 1 + src/core/eventloop.rs | 7 ------- src/core/registry.rs | 31 +++++++++++++++------------- src/nodes/data.rs | 47 +++++++++++++++++++------------------------ 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 76c8045..7d87ca4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ anyhow = "1.0.57" ctrlc = "3.2.2" flexbuffers = "2.0.0" glam = {version = "0.20.5", features = ["mint"]} +lazy_static = "1.4.0" mint = "0.5.9" mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]} rccell = "0.1.3" diff --git a/src/core/eventloop.rs b/src/core/eventloop.rs index 3d27133..6c80267 100644 --- a/src/core/eventloop.rs +++ b/src/core/eventloop.rs @@ -10,15 +10,10 @@ use std::rc::Rc; use std::sync::{Arc, RwLock}; use std::thread::{self, JoinHandle}; -use super::registry::Registry; -use crate::nodes::data::PulseSender; - pub struct EventLoop { pub socket_path: String, join_handle: RwLock>>>, stop_write: pipe::Sender, - - pub pulse_senders: Registry>, } impl EventLoop { @@ -31,8 +26,6 @@ impl EventLoop { socket_path, join_handle: RwLock::new(None), stop_write: sender, - - pulse_senders: Default::default(), }); let event_loop_arc_captured = event_loop_arc.clone(); let join_handle = thread::Builder::new() diff --git a/src/core/registry.rs b/src/core/registry.rs index 331dd3c..a1d9c0c 100644 --- a/src/core/registry.rs +++ b/src/core/registry.rs @@ -1,19 +1,27 @@ use anyhow::{anyhow, Result}; use slab::{Iter, Slab}; +use std::sync::Arc; use std::sync::RwLock; -pub struct Registry(RwLock>); +pub trait RegistryEntry { + fn store_idx(&self, idx: usize); +} -impl Registry { - pub fn add(&self, t: T) -> Result { - Ok(self +pub struct Registry(RwLock>>); + +impl Registry { + pub fn add(&self, t: T) -> Result> { + let t_arc = Arc::new(t); + let idx = self .0 .write() .ok() .ok_or_else(|| anyhow!("Registry has been poisoned"))? - .insert(t)) + .insert(t_arc.clone()); + t_arc.store_idx(idx); + Ok(t_arc) } - pub fn iterate)>(&self, closure: F) -> Result<()> { + pub fn iterate>)>(&self, closure: F) -> Result<()> { closure( self.0 .read() @@ -23,17 +31,12 @@ impl Registry { ); Ok(()) } - pub fn remove(&self, index: usize) -> Result { - Ok(self - .0 - .write() - .ok() - .ok_or_else(|| anyhow!("Registry has been poisoned"))? - .remove(index)) + pub fn remove(&self, index: usize) -> Result> { + Arc::try_unwrap(self.0.write().unwrap().remove(index)) } } -impl Default for Registry { +impl Default for Registry { fn default() -> Self { Registry::(RwLock::new(Slab::new())) } diff --git a/src/nodes/data.rs b/src/nodes/data.rs index 6098745..6cb4908 100644 --- a/src/nodes/data.rs +++ b/src/nodes/data.rs @@ -1,12 +1,16 @@ use super::core::Node; -use crate::core::eventloop::EventLoop; +use crate::core::registry::{Registry, RegistryEntry}; use anyhow::{ensure, Result}; +use lazy_static::lazy_static; use rccell::RcCell; -use std::sync::{Arc, RwLock, Weak}; +use std::sync::RwLock; + +lazy_static! { + static ref PULSE_SENDER_REGISTRY: Registry = Default::default(); +} pub struct PulseSender { - event_loop: Weak, - registry_idx: RwLock>, + registry_idx: RwLock, } impl PulseSender { @@ -16,32 +20,23 @@ impl PulseSender { "Node does not have a spatial attached!" ); - let sender = Arc::new(PulseSender { - event_loop: node.borrow().get_client().map_or(Weak::new(), |client| { - Arc::downgrade(&client.get_event_loop()) - }), - registry_idx: RwLock::new(None), - }); - let idx = sender - .event_loop - .upgrade() - .and_then(|event_loop| event_loop.pulse_senders.add(sender.clone()).ok()); - *sender.registry_idx.write().unwrap() = idx; + let sender = PulseSender { + registry_idx: Default::default(), + }; + let sender = PULSE_SENDER_REGISTRY.add(sender)?; node.borrow_mut().pulse_sender = Some(sender); Ok(()) } } -impl Drop for PulseSender { - fn drop(&mut self) { - let event_loop = self.event_loop.upgrade(); - let idx = self - .registry_idx - .write() - .ok() - .and_then(|registry_idx| registry_idx.clone()); - event_loop - .zip(idx) - .and_then(|(event_loop, idx)| event_loop.pulse_senders.remove(idx).ok()); +impl RegistryEntry for PulseSender { + fn store_idx(&self, store_idx: usize) { + *self.registry_idx.write().unwrap() = store_idx; + } +} + +impl Drop for PulseSender { + fn drop(&mut self) { + let _ = PULSE_SENDER_REGISTRY.remove(*self.registry_idx.read().unwrap()); } }