Skip to content

Instantly share code, notes, and snippets.

@dash1291
Created July 9, 2015 22:32
Show Gist options
  • Save dash1291/6f459784e564bfd3eaf9 to your computer and use it in GitHub Desktop.
Save dash1291/6f459784e564bfd3eaf9 to your computer and use it in GitHub Desktop.
fifo queue with multithreaded server for I/O
use std::io;
use std::net::TcpListener;
use std::thread;
use std::io::Read;
use std::io::Write;
use std::sync::Mutex;
use std::sync::Arc;
struct Node {
value: String,
next: Option<Box<Node>>
}
struct List {
head: Option<Box<Node>>
}
impl Node {
fn attach_new(&mut self, val: String) {
match self.next {
Some (ref mut next) => next.attach_new(val),
None => self.next = Some(Box::new(Node {value: val, next: None}))
}
}
}
impl List {
fn push_back(&mut self, val: String) {
match self.head {
Some(ref mut node) => node.attach_new(val),
None => self.head = Some(Box::new(Node {value: val, next: None}))
}
}
fn pull_front(&mut self) -> String {
if self.head.is_some() {
let detached_head = self.head.take().unwrap();
let ret_val = detached_head.value.clone();
self.head = detached_head.next;
return ret_val;
} else {
return "NO_VALUE".to_string();
}
}
}
fn input_reader(list: &mut List, input: String) -> Option<String> {
if input == "POP" {
return Some(list.pull_front());
} else {
let pieces: Vec<&str> = input.split(" ").collect();
if pieces[0] == "PUSH" {
list.push_back(pieces[1].to_string());
}
return None;
}
}
fn main() {
let mut queue = List {head: None};
let mut shared_queue = Arc::new(Mutex::new(queue));
let mut input = String::new();
let listener = TcpListener::bind("127.0.0.1:8891").unwrap();
println!("listening started, ready to accept");
for stream in listener.incoming() {
let child_queue = shared_queue.clone();
thread::spawn (move || {
let mut line_vect:Vec<u8> = Vec::new();
let mut stream = stream.unwrap();
let mut c:[u8; 1] = [0];
loop {
let n = stream.read(&mut c);
// This is the end.
if n.unwrap() == 0 {
break;
}
if (c[0] as char) == '\n' || c[0] == 13 {
if line_vect.len() > 0 {
let mut locked_queue = child_queue.lock().unwrap();
let result = input_reader(&mut locked_queue, String::from_utf8(line_vect.clone()).unwrap());
match result {
Some(res) => stream.write(&mut *(res + "\n").into_bytes()),
None => stream.write(&mut *("NO_VALUE\n".to_string().into_bytes()))
};
line_vect.clear();
}
} else {
line_vect.push(c[0]);
}
}
println!("Connection closed. Serving next.");
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment