use std::sync::{Arc, Mutex};
use std::thread;
use std::thread::JoinHandle;
use crate::common::clientport::ClientPort;
use crate::server::client::ClientManager;
pub struct PortManager {}
impl PortManager {
pub fn prune_unused_ports(client_ports: Arc<Mutex< Vec<Arc<Mutex<ClientPort>>> >>, client_manager: Arc<Mutex<ClientManager>>, thread_func: fn (Arc<Mutex<ClientPort>>, Arc<Mutex<ClientManager>>) -> JoinHandle<()>) -> JoinHandle<()> {
thread::spawn(move || {
let previous_client_send_ports: Vec<ClientPort> = Vec::new();
loop {
println!("{}", client_ports.lock().unwrap().len());
thread::sleep(std::time::Duration::from_millis(10));
let mut client_send_ports = client_ports.lock().unwrap();
let mut newly_added_ports: Vec<&Arc<Mutex<ClientPort>>> = Vec::new();
for _port in client_send_ports.iter() {
let port = _port.lock().unwrap();
let mut found = false;
for prev_port in previous_client_send_ports.iter() {
if port.port == prev_port.port {
found = true;
break;
}
}
if !found {
println!("Client send port {} added", port.port);
newly_added_ports.push(_port);
}
}
let mut newly_removed_ports: Vec<Arc<Mutex<ClientPort>>> = Vec::new();
for prev_port in previous_client_send_ports.iter() {
let mut found = false;
for _port in client_send_ports.iter() {
let port = _port.lock().unwrap();
if port.port == prev_port.port {
found = true;
break;
}
}
if !found {
println!("Client send port {} removed", prev_port.port);
let new = Arc::new(Mutex::new(prev_port.clone()));
newly_removed_ports.push(new);
}
}
newly_added_ports.iter().for_each(|_port| {
let port = _port.lock().unwrap();
let index = client_send_ports.iter().position(|p| p.lock().unwrap().port == port.port).unwrap();
let crp = client_send_ports.get(index).unwrap().clone();
let handle = thread_func(crp, client_manager.clone());
let crp_index = client_send_ports.iter().position(|crp| crp.lock().unwrap().port == port.port).unwrap();
let mut crp = client_send_ports.get(crp_index).unwrap().lock().unwrap();
crp.set_handle(handle);
});
newly_removed_ports.iter().for_each(|_port| {
let port = _port.lock().unwrap();
let index = client_send_ports.iter().position(|p| p.lock().unwrap().port == port.port).unwrap();
client_send_ports.remove(index);
});
}
})
}
pub fn allocate_port_if_necessary(client_ports: Arc<Mutex< Vec<Arc<Mutex<ClientPort>>> >>, client_manager: Arc<Mutex<ClientManager>>, port_num: u16, thread_func: fn (Arc<Mutex<ClientPort>>, Arc<Mutex<ClientManager>>) -> JoinHandle<()>) {
println!("Ports in use: {}", client_ports.lock().unwrap().len());
thread::sleep(std::time::Duration::from_millis(10));
let mut client_send_ports = client_ports.lock().unwrap();
let mut exists = false;
for _port in client_send_ports.iter() {
let port = _port.lock().unwrap();
exists = port.port == port_num;
if exists {
println!("Port already exists");
break;
}
}
if !exists {
println!("Client send port {} added", port_num);
} else {
println!("Client send port {} already exists", port_num);
return;
}
let mut crp = ClientPort {
port: port_num,
connected_client_ids: vec![],
handle: None
};
let handle = thread_func(Arc::new(Mutex::new(crp.clone())), client_manager.clone());
crp.set_handle(handle);
client_send_ports.push(Arc::new(Mutex::new(crp.clone())));
}
}