feat(client+eventloop): get arc reference to event loop in client

This commit is contained in:
Nova
2022-06-11 23:16:59 -04:00
parent 30a03f638f
commit d98dc1ee96
2 changed files with 27 additions and 11 deletions

View File

@@ -1,18 +1,22 @@
use super::eventloop::EventLoop;
use super::scenegraph::Scenegraph; use super::scenegraph::Scenegraph;
use crate::nodes::field; use crate::nodes::field;
use crate::nodes::spatial; use crate::nodes::spatial;
use libstardustxr::messenger::Messenger; use libstardustxr::messenger::Messenger;
use mio::net::UnixStream; use mio::net::UnixStream;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Weak};
pub struct Client<'a> { pub struct Client<'a> {
event_loop: Weak<EventLoop>,
messenger: Messenger<'a>, messenger: Messenger<'a>,
scenegraph: Scenegraph<'a>, scenegraph: Scenegraph<'a>,
} }
impl<'a> Client<'a> { impl<'a> Client<'a> {
pub fn from_connection(connection: UnixStream) -> Rc<Self> { pub fn from_connection(connection: UnixStream, event_loop_ref: &Arc<EventLoop>) -> Rc<Self> {
let client = Rc::new(Client { let client = Rc::new(Client {
event_loop: Arc::downgrade(event_loop_ref),
messenger: Messenger::new(connection), messenger: Messenger::new(connection),
scenegraph: Default::default(), scenegraph: Default::default(),
}); });

View File

@@ -7,23 +7,31 @@ use mio::{Events, Interest, Poll, Token};
use slab::Slab; use slab::Slab;
use std::io::Write; use std::io::Write;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, RwLock};
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
pub struct EventLoop { pub struct EventLoop {
pub socket_path: String, pub socket_path: String,
join_handle: Option<JoinHandle<Result<()>>>, join_handle: RwLock<Option<JoinHandle<Result<()>>>>,
stop_write: pipe::Sender, stop_write: pipe::Sender,
} }
impl EventLoop { impl EventLoop {
pub fn new(timeout: Option<core::time::Duration>) -> Result<Self> { pub fn new(timeout: Option<core::time::Duration>) -> Result<Arc<Self>> {
let socket_path = server::get_free_socket_path() let socket_path = server::get_free_socket_path()
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?; .ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?;
let mut socket = UnixListener::bind(socket_path.clone())?; let mut socket = UnixListener::bind(socket_path.clone())?;
let (sender, mut receiver) = pipe::new()?; let (sender, mut receiver) = pipe::new()?;
let event_loop_arc = Arc::new(EventLoop {
socket_path,
join_handle: RwLock::new(None),
stop_write: sender,
});
let event_loop_arc_captured = event_loop_arc.clone();
let join_handle = thread::Builder::new() let join_handle = thread::Builder::new()
.name("event_loop".to_owned()) .name("event_loop".to_owned())
.spawn(move || -> Result<()> { .spawn(move || -> Result<()> {
let event_loop_arc = event_loop_arc_captured;
let mut clients: Slab<Option<Rc<Client>>> = Slab::new(); let mut clients: Slab<Option<Rc<Client>>> = Slab::new();
let mut poll = Poll::new()?; let mut poll = Poll::new()?;
let mut events = Events::with_capacity(1024); let mut events = Events::with_capacity(1024);
@@ -46,7 +54,8 @@ impl EventLoop {
Token(client_number), Token(client_number),
Interest::READABLE, Interest::READABLE,
)?; )?;
let client = Client::from_connection(socket); let client =
Client::from_connection(socket, &event_loop_arc);
*clients.get_mut(client_number).unwrap() = Some(client); *clients.get_mut(client_number).unwrap() = Some(client);
} }
Err(e) => { Err(e) => {
@@ -74,11 +83,12 @@ impl EventLoop {
} }
}) })
.ok(); .ok();
Ok(EventLoop { event_loop_arc.set_join_handle(join_handle);
socket_path, Ok(event_loop_arc)
join_handle, }
stop_write: sender,
}) fn set_join_handle(&self, handle: Option<JoinHandle<Result<()>>>) {
*self.join_handle.write().unwrap() = handle;
} }
} }
@@ -88,8 +98,10 @@ impl Drop for EventLoop {
let _ = self.stop_write.write(buf.as_slice()); let _ = self.stop_write.write(buf.as_slice());
let _ = self let _ = self
.join_handle .join_handle
.take() .get_mut()
.map(|handle| handle.join()) .ok()
.and_then(|handle| handle.take())
.and_then(|handle| handle.join().ok())
.expect("Couldn't join the event loop thread at drop"); .expect("Couldn't join the event loop thread at drop");
} }
} }