Use channel for server messages in client threads

This commit is contained in:
Artlef 2020-03-07 22:46:40 +01:00
parent 3725457134
commit b7ca43be33

View File

@ -7,6 +7,7 @@ use shakmaty::{Chess, Color, Outcome, Position, Setup};
use std::io; use std::io;
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, Receiver, TryRecvError};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use std::time; use std::time;
@ -16,7 +17,7 @@ struct Client {
side: Color, side: Color,
running: Arc<AtomicBool>, running: Arc<AtomicBool>,
input_buffer: Arc<Mutex<String>>, input_buffer: Arc<Mutex<String>>,
server_message: Arc<Mutex<String>>, server_message_recv: Receiver<String>,
} }
fn main() { fn main() {
@ -38,7 +39,7 @@ fn main() {
clichess::write_to_stream(&mut stream, username_pubkey_json.to_string()).unwrap(); clichess::write_to_stream(&mut stream, username_pubkey_json.to_string()).unwrap();
let input_buffer = setup_input_buffer(); let input_buffer = setup_input_buffer();
//start a thread to listen to server messages //start a thread to listen to server messages
let server_message = setup_server_message_recv(&stream).unwrap(); let server_message_recv = setup_server_message_recv(&stream).unwrap();
let mut client = Client { let mut client = Client {
player: clichess::Player { player: clichess::Player {
@ -49,7 +50,7 @@ fn main() {
side: Color::White, side: Color::White,
running: running.clone(), running: running.clone(),
input_buffer: input_buffer.clone(), input_buffer: input_buffer.clone(),
server_message: server_message.clone(), server_message_recv,
}; };
match prompt_user_for_role(&client, &mut stream) { match prompt_user_for_role(&client, &mut stream) {
@ -139,9 +140,9 @@ fn setupctrlc() -> Arc<AtomicBool> {
running running
} }
fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Arc<Mutex<String>>> { fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Receiver<String>> {
let buf = Arc::new(Mutex::new(String::new())); let buf = Arc::new(Mutex::new(String::new()));
let buf2 = buf.clone(); let (sender, receiver) = channel();
let thread_stream = stream.try_clone()?; let thread_stream = stream.try_clone()?;
thread::spawn(move || { thread::spawn(move || {
@ -149,17 +150,10 @@ fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Arc<Mutex<String
//wait for server message //wait for server message
let buffer = let buffer =
clichess::read_line_from_stream(&thread_stream).expect("Error message from server"); clichess::read_line_from_stream(&thread_stream).expect("Error message from server");
{ sender.send(buffer).unwrap();
let mut server_message = buf2.lock().unwrap();
if server_message.is_empty() {
*server_message = buffer;
} else {
println!("Warning: server tried to send a message while the current one has not been computed yet.");
}
}
} }
}); });
Ok(buf) Ok(receiver)
} }
fn read_user_input(client: &Client) -> String { fn read_user_input(client: &Client) -> String {
@ -203,14 +197,15 @@ fn fetch_message_from_server(client: &Client) -> String {
while client.running.load(Ordering::SeqCst) { while client.running.load(Ordering::SeqCst) {
thread::sleep(time::Duration::from_millis(10)); thread::sleep(time::Duration::from_millis(10));
{ {
let mut server_response = client.server_message.lock().unwrap(); let server_response_recv = &client.server_message_recv;
if server_response.is_empty() { match server_response_recv.try_recv() {
continue; Ok(msg) => {
} else { response = msg;
response = server_response.clone();
server_response.clear();
break; break;
} }
Err(TryRecvError::Disconnected) => println!("Error: server disconnected."),
Err(TryRecvError::Empty) => continue,
}
} }
} }
response response