diff options
| author | Arne Dußin | 2021-02-04 14:15:20 +0100 |
|---|---|---|
| committer | Arne Dußin | 2021-02-04 14:15:20 +0100 |
| commit | c0f8c067f6226981dc657a5a13fe0c0c5b0734d9 (patch) | |
| tree | a3f5aa2eedb6fa3215e05d582a51855ee6563402 /src | |
| parent | 5652a771352ca0c9c344cd8d28dab291e8c415dc (diff) | |
| download | graf_karto-c0f8c067f6226981dc657a5a13fe0c0c5b0734d9.tar.gz graf_karto-c0f8c067f6226981dc657a5a13fe0c0c5b0734d9.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/client_main.rs | 8 | ||||
| -rw-r--r-- | src/server/mod.rs | 129 |
2 files changed, 74 insertions, 63 deletions
diff --git a/src/client_main.rs b/src/client_main.rs index 70dd857..43660d7 100644 --- a/src/client_main.rs +++ b/src/client_main.rs @@ -32,6 +32,7 @@ pub mod world; use clap::{App, Arg}; use server::DEFAULT_PORT; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs}; +use std::sync::atomic::Ordering; fn main() { pretty_env_logger::init(); @@ -72,10 +73,10 @@ fn main() { let server_handle = if !matches.is_present("connect") { Some({ - let (server_handle, port) = + let (server_handle, server_running, port) = server::start_any_port(use_ipv4).expect("Unable to start local server"); server_port = port; - server_handle + (server_handle, server_running) }) } else { None @@ -111,7 +112,8 @@ fn main() { client::run(dbg!(server_address)); - if let Some(handle) = server_handle { + if let Some((handle, running)) = server_handle { + running.store(false, Ordering::Relaxed); handle.join().expect("Server thread closed unexpectedly."); } } 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<JoinHandle<()>, 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<AtomicBool>, 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<Cargo>) -> JoinHandle<()> { +fn start(conn_man: ConnectionManager<Cargo>) -> (JoinHandle<()>, Arc<AtomicBool>) { 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) } |
