From c0f8c067f6226981dc657a5a13fe0c0c5b0734d9 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Thu, 4 Feb 2021 14:15:20 +0100 Subject: Make the server started by the client shut down Before, the server thread would just continue running, after the window had been closed. This is fixed now, with the server thread being controlled by an atomic bool. --- src/server/mod.rs | 129 +++++++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 60 deletions(-) (limited to 'src/server') diff --git a/src/server/mod.rs b/src/server/mod.rs index c9550f7..4f95378 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -5,6 +5,8 @@ use crate::net::Cargo; use crate::world::World; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; use std::thread::{self, JoinHandle}; /// The default port the dedicated graf karto server runs on. @@ -25,85 +27,92 @@ pub fn start_with_port(port: u16, ipv4: bool) -> Result, io::Erro let addr = unspecified(port, ipv4); let conn_man = ConnectionManager::start(addr)?; - Ok(start(conn_man)) + Ok(start(conn_man).0) } /// Starts a thread on any free system port. Returns an error in case that's not /// possible. -pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, u16), io::Error> { +pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, Arc, u16), io::Error> { let addr = unspecified(0, ipv4); let conn_man = ConnectionManager::start(addr)?; let port = conn_man.port(); - Ok((start(conn_man), port)) + let (handle, running) = start(conn_man); + Ok((handle, running, port)) } -fn start(conn_man: ConnectionManager) -> JoinHandle<()> { +fn start(conn_man: ConnectionManager) -> (JoinHandle<()>, Arc) { info!("Server started on port {}", conn_man.port()); + let running = Arc::new(AtomicBool::new(true)); + let running_cl = running.clone(); let mut world = World::new(); - thread::spawn(move || loop { - if let Some((user, cargo)) = conn_man.next_packet() { - match cargo { - Cargo::AddRoom(room) => { - let room_id = world.push_room(room.clone()); - conn_man.broadcast(Cargo::SetRoom((room_id, room))); - } - Cargo::AddIcon(icon) => { - let icon_id = world.push_icon(icon.clone()); - conn_man.broadcast(Cargo::SetIcon((icon_id, icon))); - } - Cargo::AddWall(wall) => { - let wall_id = world.push_wall(wall.clone()); - conn_man.broadcast(Cargo::SetWall((wall_id, wall))); - } - Cargo::SetRoom((id, new)) => { - if let Some(old) = world.get_room_mut(id) { - *old = new; - } else { - error!( - "Unable to change room. Room with id `{}` does not exist.", - id - ); + let handle = thread::spawn(move || { + while running_cl.load(Ordering::Relaxed) { + if let Some((_user, cargo)) = conn_man.next_packet() { + match cargo { + Cargo::AddRoom(room) => { + let room_id = world.push_room(room.clone()); + conn_man.broadcast(Cargo::SetRoom((room_id, room))); } - } - Cargo::SetIcon((id, new)) => { - if let Some(old) = world.get_icon_mut(id) { - *old = new; - } else { - error!( - "Unable to change icon. Icon with id `{}` does not exist.", - id - ); + Cargo::AddIcon(icon) => { + let icon_id = world.push_icon(icon.clone()); + conn_man.broadcast(Cargo::SetIcon((icon_id, icon))); } - } - Cargo::SetWall((id, new)) => { - if let Some(old) = world.get_wall_mut(id) { - *old = new; - } else { - error!( - "Unable to change wall. Wall with id `{}` does not exist.", - id - ); + Cargo::AddWall(wall) => { + let wall_id = world.push_wall(wall.clone()); + conn_man.broadcast(Cargo::SetWall((wall_id, wall))); } - } - Cargo::ClearAll => { - world.clear(); - conn_man.broadcast(Cargo::ClearAll); - } - Cargo::Remove(id) => { - if world.remove(id) { - conn_man.broadcast(Cargo::Remove(id)); - } else { - error!("Unable to remove item. No item with id `{}` found.", id); + Cargo::SetRoom((id, new)) => { + if let Some(old) = world.get_room_mut(id) { + *old = new; + } else { + error!( + "Unable to change room. Room with id `{}` does not exist.", + id + ); + } + } + Cargo::SetIcon((id, new)) => { + if let Some(old) = world.get_icon_mut(id) { + *old = new; + } else { + error!( + "Unable to change icon. Icon with id `{}` does not exist.", + id + ); + } + } + Cargo::SetWall((id, new)) => { + if let Some(old) = world.get_wall_mut(id) { + *old = new; + } else { + error!( + "Unable to change wall. Wall with id `{}` does not exist.", + id + ); + } + } + Cargo::ClearAll => { + world.clear(); + conn_man.broadcast(Cargo::ClearAll); + } + Cargo::Remove(id) => { + if world.remove(id) { + conn_man.broadcast(Cargo::Remove(id)); + } else { + error!("Unable to remove item. No item with id `{}` found.", id); + } + } + Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(), + Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => { + error!("This packet is not allowed in the client -> server direction"); } - } - Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(), - Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => { - error!("This packet is not allowed in the client -> server direction"); } } } - }) + }); + + (handle, running) } -- cgit v1.2.3-70-g09d2