diff --git a/network/windows/src/allocator.rs b/network/windows/src/eventloop/allocator.rs similarity index 95% rename from network/windows/src/allocator.rs rename to network/windows/src/eventloop/allocator.rs index a415044..ecee487 100644 --- a/network/windows/src/allocator.rs +++ b/network/windows/src/eventloop/allocator.rs @@ -3,7 +3,7 @@ use std::mem::uninitialized; use std::pin::Pin; use std::ptr; -pub(super) struct Allocator { +pub(crate) struct Allocator { map: HashMap>>, } diff --git a/network/windows/src/eventloop/mod.rs b/network/windows/src/eventloop/mod.rs new file mode 100644 index 0000000..127bb9b --- /dev/null +++ b/network/windows/src/eventloop/mod.rs @@ -0,0 +1,123 @@ +mod socket; +mod task; +mod allocator; + +use socket::WindowsOverlappingIcmpSocket; + +use crate::address::WindowsAddressKnown; +use allocator::Allocator; +use task::IoTask; +use bgtu_networks_2_network_abstract::ServersContext; +use std::mem::uninitialized; +use std::pin::Pin; +use std::ptr::NonNull; +use windows::Win32::System::IO::OVERLAPPED; +use windows::Win32::System::Threading::SleepEx; + +pub unsafe fn run_eventloop>(ctx: *mut Ctx) { + let mut heap = Allocator::>>::new(); + + let mut socket = WindowsOverlappingIcmpSocket::new(); + + let mut recv_task = NonNull::from_mut(&mut heap).as_mut().alloc(); + CallbackData::init_recv( + &mut recv_task, + NonNull::new_unchecked(ctx), + NonNull::from_mut(&mut heap), + ); + + let mut is_receive_enabled = false; + + loop { + let (id, it) = (*ctx).start_measuring(); + + let mut should_recv_being_enabled = false; + for address in it { + let mut task = NonNull::from_mut(&mut heap).as_mut().alloc(); + CallbackData::init_send( + &mut task, + NonNull::new_unchecked(ctx), + NonNull::from_mut(&mut heap), + address, + ); + + socket.send(&mut task, Some(sending_done::)); + should_recv_being_enabled = true; + } + + if (!is_receive_enabled && should_recv_being_enabled) { + socket.receive(&mut recv_task, Some(receiving_done::)); + is_receive_enabled = true; + } + + SleepEx(1000, true); + } +} + +struct CallbackData> { + ctx: NonNull, + allocator: NonNull>>, + address: WindowsAddressKnown, + __flags: u32, + __addrs_size: i32, +} + +impl> CallbackData { + fn init_send( + task: &mut Pin<&mut IoTask>>, + ctx: NonNull, + allocator: NonNull>>, + address: WindowsAddressKnown, + ) { + task.init(Self { + ctx, + allocator, + address, + __flags: unsafe { uninitialized() }, + __addrs_size: unsafe { uninitialized() }, + }); + } + fn init_recv( + task: &mut Pin<&mut IoTask>>, + ctx: NonNull, + allocator: NonNull>>, + ) { + task.init(Self { + ctx, + allocator, + address: unsafe { uninitialized() }, + __flags: unsafe { uninitialized() }, + __addrs_size: unsafe { uninitialized() }, + }); + } +} + +unsafe extern "system" fn sending_done>( + dwerror: u32, + cbtransferred: u32, + lpoverlapped: *mut OVERLAPPED, + dwflags: u32, +) { + let mut task = Pin::new_unchecked( + lpoverlapped + .cast::>>() + .as_mut() + .unwrap(), + ); + task.get_extra().allocator.as_mut().free(task); +} + +unsafe extern "system" fn receiving_done>( + dwerror: u32, + cbtransferred: u32, + lpoverlapped: *mut OVERLAPPED, + dwflags: u32, +) { + let mut task = Pin::new_unchecked( + lpoverlapped + .cast::>>() + .as_mut() + .unwrap(), + ); + task.get_extra().allocator.as_mut().free(task); +} diff --git a/network/windows/src/eventloop.rs b/network/windows/src/eventloop/socket.rs similarity index 55% rename from network/windows/src/eventloop.rs rename to network/windows/src/eventloop/socket.rs index 8cd95f3..3c2193a 100644 --- a/network/windows/src/eventloop.rs +++ b/network/windows/src/eventloop/socket.rs @@ -1,9 +1,8 @@ use crate::address::WindowsAddressKnown; -use crate::allocator::Allocator; use crate::errors::throw_from_windows_err_code; -use crate::task::IoTask; +use crate::eventloop::CallbackData; +use crate::eventloop::task::IoTask; use bgtu_networks_2_network_abstract::ServersContext; -use std::mem::uninitialized; use std::pin::Pin; use std::ptr::NonNull; use windows::Win32::Networking::WinSock::{ @@ -15,123 +14,12 @@ use windows::Win32::Networking::WinSock::{ WSAENOTSOCK, WSAESHUTDOWN, WSAEWOULDBLOCK, WSAGetLastError, WSANOTINITIALISED, WSARecvFrom, WSASendTo, WSASocketW, }; -use windows::Win32::System::IO::OVERLAPPED; -use windows::Win32::System::Threading::SleepEx; -pub unsafe fn run_eventloop>(ctx: *mut Ctx) { - let mut heap = Allocator::>>::new(); - - let mut socket = WindowsOverlappingIcmpSocket::new(); - - let mut recv_task = NonNull::from_mut(&mut heap).as_mut().alloc(); - CallbackData::init_recv( - &mut recv_task, - NonNull::new_unchecked(ctx), - NonNull::from_mut(&mut heap), - ); - - let mut is_receive_enabled = false; - - loop { - let (id, it) = (*ctx).start_measuring(); - - let mut should_recv_being_enabled = false; - for address in it { - let mut task = NonNull::from_mut(&mut heap).as_mut().alloc(); - CallbackData::init_send( - &mut task, - NonNull::new_unchecked(ctx), - NonNull::from_mut(&mut heap), - address, - ); - - socket.send(&mut task, Some(sending_done::)); - should_recv_being_enabled = true; - } - - if (!is_receive_enabled && should_recv_being_enabled) { - socket.receive(&mut recv_task, Some(receiving_done::)); - is_receive_enabled = true; - } - - SleepEx(1000, true); - } -} - -struct CallbackData> { - ctx: NonNull, - allocator: NonNull>>, - address: WindowsAddressKnown, - __flags: u32, - __addrs_size: i32, -} - -impl> CallbackData { - fn init_send( - task: &mut Pin<&mut IoTask>>, - ctx: NonNull, - allocator: NonNull>>, - address: WindowsAddressKnown, - ) { - task.init(Self { - ctx, - allocator, - address, - __flags: unsafe { uninitialized() }, - __addrs_size: unsafe { uninitialized() }, - }); - } - fn init_recv( - task: &mut Pin<&mut IoTask>>, - ctx: NonNull, - allocator: NonNull>>, - ) { - task.init(Self { - ctx, - allocator, - address: unsafe { uninitialized() }, - __flags: unsafe { uninitialized() }, - __addrs_size: unsafe { uninitialized() }, - }); - } -} - -unsafe extern "system" fn sending_done>( - dwerror: u32, - cbtransferred: u32, - lpoverlapped: *mut OVERLAPPED, - dwflags: u32, -) { - let mut task = Pin::new_unchecked( - lpoverlapped - .cast::>>() - .as_mut() - .unwrap(), - ); - task.get_extra().allocator.as_mut().free(task); -} - -unsafe extern "system" fn receiving_done>( - dwerror: u32, - cbtransferred: u32, - lpoverlapped: *mut OVERLAPPED, - dwflags: u32, -) { - let mut task = Pin::new_unchecked( - lpoverlapped - .cast::>>() - .as_mut() - .unwrap(), - ); - task.get_extra().allocator.as_mut().free(task); -} - -struct WindowsOverlappingIcmpSocket { +pub(super) struct WindowsOverlappingIcmpSocket { s: SOCKET, } - impl WindowsOverlappingIcmpSocket { - fn new() -> Self { + pub fn new() -> Self { let result = unsafe { WSASocketW( AF_UNSPEC.0 as i32, @@ -149,7 +37,7 @@ impl WindowsOverlappingIcmpSocket { } } - unsafe fn send>( + pub unsafe fn send>( &mut self, task: &mut Pin<&mut IoTask>>, cb: LPWSAOVERLAPPED_COMPLETION_ROUTINE, @@ -200,7 +88,7 @@ impl WindowsOverlappingIcmpSocket { } } - unsafe fn receive>( + pub unsafe fn receive>( &mut self, task: &mut Pin<&mut IoTask>>, cb: LPWSAOVERLAPPED_COMPLETION_ROUTINE, diff --git a/network/windows/src/task.rs b/network/windows/src/eventloop/task.rs similarity index 100% rename from network/windows/src/task.rs rename to network/windows/src/eventloop/task.rs diff --git a/network/windows/src/lib.rs b/network/windows/src/lib.rs index 65a86b1..b3dbfaa 100644 --- a/network/windows/src/lib.rs +++ b/network/windows/src/lib.rs @@ -1,8 +1,6 @@ mod address; mod errors; -mod task; mod eventloop; -mod allocator; mod entry_point; mod network_context;