Network thread termination

This commit is contained in:
Andrew Golovashevich 2026-03-11 01:57:42 +03:00
parent 953391dd2f
commit 38a8b4bd2b
8 changed files with 55 additions and 9 deletions

View File

@ -8,6 +8,7 @@ workspace = true
[dependencies]
bgtu-networks-2-network-abstract = { path = "../network/abstract" }
bgtu-networks-2-gui-abstract = { path = "../gui/abstract" }
bgtu-networks-2-gui-egui = { path = "../gui/egui" }
bgtu-networks-2-data = { path = "../data" }

View File

@ -4,6 +4,7 @@ use bgtu_networks_2_network_windows::winsocks_scope_2_2;
use std::sync::Arc;
use std::thread;
use bgtu_networks_2_gui_egui::run_eframe_gui;
use bgtu_networks_2_gui_abstract::ServersStorage as ServersGuiCtx;
fn main() {
winsocks_scope_2_2(NetworkMain {});
@ -21,10 +22,21 @@ impl NetworkScope for NetworkMain {
s.spawn(|| {
Ctx::run_ping_eventloop(&mut storage.as_ref().new_network_ctx());
});
run_eframe_gui(&mut storage.new_gui_ctx());
let network_thread_terminator = NetworkThreadTerminator { ctx: &mut storage.new_gui_ctx() };
let _ = run_eframe_gui(&mut storage.new_gui_ctx());
drop(network_thread_terminator);
});
}
}
struct NetworkThreadTerminator<'ctx, Ctx: ServersGuiCtx> {
ctx: &'ctx mut Ctx,
}
impl<'ctx, Ctx: ServersGuiCtx> Drop for NetworkThreadTerminator<'ctx, Ctx> {
fn drop(&mut self) {
self.ctx.terminate();
}
}

View File

@ -61,6 +61,10 @@ impl<A: Address + Hash + Eq> ServersNetworkCtx<A> for _Impl<'_, A> {
let lock_scope = self.data.mutex.read();
unsafe { self.get_unprotected() }.report_error(addr, id);
}
fn is_running(&self) -> bool {
return unsafe { self.get_unprotected() }.is_running();
}
}
impl<A: Address + Hash + Eq> ServersGuiCtx for _Impl<'_, A> {
@ -94,4 +98,8 @@ impl<A: Address + Hash + Eq> ServersGuiCtx for _Impl<'_, A> {
fn graph_sections_count(&self) -> usize {
return unsafe { self.get_unprotected() }.graph_sections_count();
}
fn terminate(&mut self) {
unsafe { self.get_unprotected() }.terminate();
}
}

View File

@ -3,11 +3,13 @@ use bgtu_networks_2_gui_abstract::ServersStorage as ServersGuiCtx;
use bgtu_networks_2_network_abstract::{Address, ServersContext as ServersNetworkCtx};
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::atomic::{AtomicBool, Ordering};
pub struct ServersStorage<A: Address + Hash + Eq> {
history_capacity: usize,
last_stored_req_id: u64,
map: HashMap<A, (String, CycledBuffer<Option<u128>>)>,
is_running: AtomicBool
}
impl<A: Address + Hash + Eq> ServersStorage<A> {
@ -16,6 +18,7 @@ impl<A: Address + Hash + Eq> ServersStorage<A> {
history_capacity,
last_stored_req_id: 0,
map: HashMap::new(),
is_running: AtomicBool::new(true)
};
}
@ -42,6 +45,10 @@ impl<A: Address + Hash + Eq> ServersNetworkCtx<A> for ServersStorage<A> {
}
fn report_error(&mut self, _addr: A, _id: u64) {}
fn is_running(&self) -> bool {
return self.is_running.load(Ordering::Relaxed);
}
}
impl<A: Address + Hash + Eq> ServersGuiCtx for ServersStorage<A> {
@ -78,4 +85,8 @@ impl<A: Address + Hash + Eq> ServersGuiCtx for ServersStorage<A> {
fn graph_sections_count(&self) -> usize {
return self.history_capacity;
}
fn terminate(&mut self) {
self.is_running.store(false, Ordering::Relaxed)
}
}

View File

@ -4,9 +4,9 @@ pub trait ServersStorage {
type Address: Address;
fn add_server(&mut self, addr: Self::Address, memo: String);
fn remove_server(&mut self, addr: &Self::Address);
fn edit_memo(&mut self, addr: &Self::Address, new_memo: String);
// type TimeIterator: Iterator<Item = Option<u128>>;
@ -15,4 +15,6 @@ pub trait ServersStorage {
) -> impl Iterator<Item = (&Self::Address, &str, impl Iterator<Item = Option<u128>>)>;
fn graph_sections_count(&self) -> usize;
fn terminate(&mut self);
}

View File

@ -17,6 +17,8 @@ pub trait ServersContext<A: Address> {
fn report_ping(&mut self, addr: A, id: u64, ping_ms: u128);
fn report_error(&mut self, addr: A, id: u64);
fn is_running(&self) -> bool;
}
pub trait NetworkScope {

View File

@ -30,7 +30,7 @@ pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut
let mut seq_no = 0u16;
loop {
while (*ctx).is_running() {
let (round_id, addrs_it) = (*ctx).start_measuring();
let mut should_recv_being_enabled = false;
@ -50,7 +50,7 @@ pub unsafe fn run_eventloop<Ctx: ServersContext<WindowsAddressKnown>>(ctx: *mut
let delayStart = GetTickCount();
let delayEnd = delayStart.wrapping_add(1000);
loop {
while (*ctx).is_running() {
let current = GetTickCount();
if delayStart < delayEnd {
if current < delayEnd {

View File

@ -13,7 +13,7 @@ use windows::Win32::Networking::WinSock::{
WSAECONNRESET, WSAEDESTADDRREQ, WSAEFAULT, WSAEHOSTUNREACH, WSAEINPROGRESS, WSAEINTR,
WSAEINVAL, WSAEMSGSIZE, WSAENETDOWN, WSAENETRESET, WSAENETUNREACH, WSAENOBUFS, WSAENOTCONN,
WSAENOTSOCK, WSAESHUTDOWN, WSAEWOULDBLOCK, WSAGetLastError, WSANOTINITIALISED, WSARecvFrom,
WSASendTo, WSASocketW,
WSASendTo, WSASocketW, closesocket,
};
use windows::Win32::System::IO::OVERLAPPED;
@ -184,3 +184,13 @@ impl<'a> WindowsOverlappingIcmpSocket<'a> {
}
}
}
impl Drop for WindowsOverlappingIcmpSocket<'_> {
fn drop(&mut self) {
unsafe {
if closesocket(self.socket) == SOCKET_ERROR {
throw_from_windows_err_code(WSAGetLastError())
}
}
}
}