diff --git a/core/src/coroutine/korosensei.rs b/core/src/coroutine/korosensei.rs index f441bfa1..7697b4e6 100644 --- a/core/src/coroutine/korosensei.rs +++ b/core/src/coroutine/korosensei.rs @@ -36,12 +36,7 @@ pub struct Coroutine<'c, Param, Yield, Return> { impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { cfg_if::cfg_if! { if #[cfg(unix)] { - #[allow( - clippy::cast_possible_truncation, - clippy::too_many_lines, - clippy::cast_sign_loss, - clippy::cast_possible_wrap - )] + #[allow(clippy::too_many_lines)] extern "C" fn trap_handler( _signum: libc::c_int, _siginfo: *mut libc::siginfo_t, @@ -56,43 +51,40 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { any(target_os = "linux", target_os = "android"), target_arch = "x86_64", ))] { - let sp = context.uc_mcontext.gregs[libc::REG_RSP as usize] as usize; + let sp = u64::try_from(context.uc_mcontext.gregs[usize::try_from(libc::REG_RSP).expect("overflow")]).expect("overflow"); } else if #[cfg(all( any(target_os = "linux", target_os = "android"), target_arch = "x86", ))] { - let sp = context.uc_mcontext.gregs[libc::REG_ESP as usize] as usize; + let sp = u64::from(std::mem::transmute::<_, std::ffi::c_uint>(context.uc_mcontext.gregs[usize::try_from(libc::REG_ESP).expect("overflow")])); } else if #[cfg(all(target_vendor = "apple", target_arch = "x86_64"))] { - let sp = (*context.uc_mcontext).__ss.__rsp as usize; + let sp = u64::try_from((*context.uc_mcontext).__ss.__rsp).expect("overflow"); } else if #[cfg(all( any(target_os = "linux", target_os = "android"), target_arch = "aarch64", ))] { - let sp = context.uc_mcontext.sp as usize; + let sp = u64::try_from(context.uc_mcontext.sp).expect("overflow"); } else if #[cfg(all( any(target_os = "linux", target_os = "android"), target_arch = "arm", ))] { - let sp = context.uc_mcontext.arm_sp as usize; + let sp = u64::try_from(context.uc_mcontext.arm_sp).expect("overflow"); } else if #[cfg(all( any(target_os = "linux", target_os = "android"), any(target_arch = "riscv64", target_arch = "riscv32"), ))] { - let sp = context.uc_mcontext.__gregs[libc::REG_SP] as usize; + let sp = u64::try_from(context.uc_mcontext.__gregs[libc::REG_SP]).expect("overflow"); } else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64"))] { - let sp = (*context.uc_mcontext).__ss.__sp as usize; + let sp = (*context.uc_mcontext).__ss.__sp; } else if #[cfg(all(target_os = "linux", target_arch = "loongarch64"))] { - let sp = context.uc_mcontext.__gregs[3] as usize; + let sp = u64::try_from(context.uc_mcontext.__gregs[3]).expect("overflow"); } else { compile_error!("Unsupported platform"); } } if let Some(co) = Self::current() { - let handler = co.inner.trap_handler(); - // assert!(handler.stack_ptr_in_bounds(sp), "coroutine {} stack overflow !", co.get_name()); - // let regs = handler.setup_trap_handler(|| Err("invalid memory reference")); - let stack_ptr_in_bounds = handler.stack_ptr_in_bounds(sp); - let regs = handler.setup_trap_handler(move || { + let stack_ptr_in_bounds = co.stack_ptr_in_bounds(sp); + let regs = co.inner.trap_handler().setup_trap_handler(move || { Err(if stack_ptr_in_bounds { "invalid memory reference" } else { @@ -105,21 +97,21 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { target_arch = "x86_64", ))] { let TrapHandlerRegs { rip, rsp, rbp, rdi, rsi } = regs; - context.uc_mcontext.gregs[libc::REG_RIP as usize] = rip as i64; - context.uc_mcontext.gregs[libc::REG_RSP as usize] = rsp as i64; - context.uc_mcontext.gregs[libc::REG_RBP as usize] = rbp as i64; - context.uc_mcontext.gregs[libc::REG_RDI as usize] = rdi as i64; - context.uc_mcontext.gregs[libc::REG_RSI as usize] = rsi as i64; + context.uc_mcontext.gregs[usize::try_from(libc::REG_RIP).expect("overflow")] = std::ffi::c_longlong::try_from(rip).expect("overflow"); + context.uc_mcontext.gregs[usize::try_from(libc::REG_RSP).expect("overflow")] = std::ffi::c_longlong::try_from(rsp).expect("overflow"); + context.uc_mcontext.gregs[usize::try_from(libc::REG_RBP).expect("overflow")] = std::ffi::c_longlong::try_from(rbp).expect("overflow"); + context.uc_mcontext.gregs[usize::try_from(libc::REG_RDI).expect("overflow")] = std::ffi::c_longlong::try_from(rdi).expect("overflow"); + context.uc_mcontext.gregs[usize::try_from(libc::REG_RSI).expect("overflow")] = std::ffi::c_longlong::try_from(rsi).expect("overflow"); } else if #[cfg(all( any(target_os = "linux", target_os = "android"), target_arch = "x86", ))] { let TrapHandlerRegs { eip, esp, ebp, ecx, edx } = regs; - context.uc_mcontext.gregs[libc::REG_EIP as usize] = eip as i32; - context.uc_mcontext.gregs[libc::REG_ESP as usize] = esp as i32; - context.uc_mcontext.gregs[libc::REG_EBP as usize] = ebp as i32; - context.uc_mcontext.gregs[libc::REG_ECX as usize] = ecx as i32; - context.uc_mcontext.gregs[libc::REG_EDX as usize] = edx as i32; + context.uc_mcontext.gregs[usize::try_from(libc::REG_EIP).expect("overflow")] = std::mem::transmute(eip); + context.uc_mcontext.gregs[usize::try_from(libc::REG_ESP).expect("overflow")] = std::mem::transmute(esp); + context.uc_mcontext.gregs[usize::try_from(libc::REG_EBP).expect("overflow")] = std::mem::transmute(ebp); + context.uc_mcontext.gregs[usize::try_from(libc::REG_ECX).expect("overflow")] = std::mem::transmute(ecx); + context.uc_mcontext.gregs[usize::try_from(libc::REG_EDX).expect("overflow")] = std::mem::transmute(edx); } else if #[cfg(all(target_vendor = "apple", target_arch = "x86_64"))] { let TrapHandlerRegs { rip, rsp, rbp, rdi, rsi } = regs; (*context.uc_mcontext).__ss.__rip = rip; @@ -175,12 +167,12 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { any(target_arch = "riscv64", target_arch = "riscv32"), ))] { let TrapHandlerRegs { pc, ra, sp, a0, a1, s0 } = regs; - context.uc_mcontext.__gregs[libc::REG_PC] = pc as libc::c_ulong; - context.uc_mcontext.__gregs[libc::REG_RA] = ra as libc::c_ulong; - context.uc_mcontext.__gregs[libc::REG_SP] = sp as libc::c_ulong; - context.uc_mcontext.__gregs[libc::REG_A0] = a0 as libc::c_ulong; - context.uc_mcontext.__gregs[libc::REG_A0 + 1] = a1 as libc::c_ulong; - context.uc_mcontext.__gregs[libc::REG_S0] = s0 as libc::c_ulong; + context.uc_mcontext.__gregs[libc::REG_PC] = std::ffi::c_ulong::try_from(pc).expect("overflow"); + context.uc_mcontext.__gregs[libc::REG_RA] = std::ffi::c_ulong::try_from(ra).expect("overflow"); + context.uc_mcontext.__gregs[libc::REG_SP] = std::ffi::c_ulong::try_from(sp).expect("overflow"); + context.uc_mcontext.__gregs[libc::REG_A0] = std::ffi::c_ulong::try_from(a0).expect("overflow"); + context.uc_mcontext.__gregs[libc::REG_A0 + 1] = std::ffi::c_ulong::try_from(a1).expect("overflow"); + context.uc_mcontext.__gregs[libc::REG_S0] = std::ffi::c_ulong::try_from(s0).expect("overflow"); } else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64"))] { let TrapHandlerRegs { pc, sp, x0, x1, x29, lr } = regs; (*context.uc_mcontext).__ss.__pc = pc; @@ -214,23 +206,16 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { if let Some(co) = Self::current() { cfg_if::cfg_if! { if #[cfg(target_arch = "x86_64")] { - let sp = usize::try_from((*(*exception_info).ContextRecord).Rsp).expect("parse RSP failed"); + let sp = (*(*exception_info).ContextRecord).Rsp; } else if #[cfg(target_arch = "x86")] { - let sp = (*(*exception_info).ContextRecord).Esp as usize; + let sp = u64::from((*(*exception_info).ContextRecord).Esp); } else { compile_error!("Unsupported platform"); } } - let handler = co.inner.trap_handler(); - // if !handler.stack_ptr_in_bounds(sp) { - // // EXCEPTION_CONTINUE_SEARCH - // crate::error!("coroutine {} stack overflow !", co.get_name()); - // return 0; - // } - // let regs = handler.setup_trap_handler(|| Err("invalid memory reference")); - let stack_ptr_in_bounds = handler.stack_ptr_in_bounds(sp); - let regs = handler.setup_trap_handler(move || { + let stack_ptr_in_bounds = co.stack_ptr_in_bounds(sp); + let regs = co.inner.trap_handler().setup_trap_handler(move || { Err(if stack_ptr_in_bounds { "invalid memory reference" } else { diff --git a/core/src/coroutine/mod.rs b/core/src/coroutine/mod.rs index 681fe7e9..950d4c8e 100644 --- a/core/src/coroutine/mod.rs +++ b/core/src/coroutine/mod.rs @@ -96,6 +96,22 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> { self.stack_infos.borrow().clone() } + /// Checks whether the stack pointer at the point where a trap occurred is + /// within the coroutine that this `CoroutineTrapHandler` was produced from. + /// This check includes any guard pages on the stack and will therefore + /// still return true in the case of a stack overflow. + /// + /// The result of this function is only meaningful if the coroutine has not + /// been dropped yet. + pub fn stack_ptr_in_bounds(&self, stack_ptr: u64) -> bool { + for info in self.stack_infos.borrow().iter() { + if info.stack_bottom as u64 <= stack_ptr && stack_ptr < info.stack_top as u64 { + return true; + } + } + false + } + /// Grows the call stack if necessary. /// /// This function is intended to be called at manually instrumented points in a program where diff --git a/core/src/syscall/common.rs b/core/src/syscall/common.rs deleted file mode 100644 index 1420303c..00000000 --- a/core/src/syscall/common.rs +++ /dev/null @@ -1,52 +0,0 @@ -pub use crate::syscall::{ - is_blocking, is_non_blocking, recv_time_limit, send_time_limit, set_blocking, set_errno, - set_non_blocking, -}; - -pub extern "C" fn reset_errno() { - set_errno(0); -} - -#[macro_export] -macro_rules! syscall_mod { - ($($mod_name: ident);*) => { - $( - pub use $mod_name::$mod_name; - mod $mod_name; - )* - } -} - -#[macro_export] -macro_rules! log_syscall { - ( $socket:expr, $done:expr, $once_result:expr ) => { - #[cfg(feature = "logs")] - if let Some(coroutine) = $crate::scheduler::SchedulableCoroutine::current() { - $crate::info!( - "{} {} {} {} {} {}", - coroutine.get_name(), - coroutine.state(), - $socket, - $done, - $once_result, - std::io::Error::last_os_error(), - ); - } - }; -} - -#[macro_export] -macro_rules! impl_non_blocking { - ( $socket:expr, $impls:expr ) => {{ - let socket = $socket; - let blocking = $crate::syscall::common::is_blocking(socket); - if blocking { - $crate::syscall::common::set_non_blocking(socket); - } - let r = $impls; - if blocking { - $crate::syscall::common::set_blocking(socket); - } - return r; - }}; -} diff --git a/core/src/syscall/mod.rs b/core/src/syscall/mod.rs index 81ab16c8..0e34350c 100644 --- a/core/src/syscall/mod.rs +++ b/core/src/syscall/mod.rs @@ -1,4 +1,11 @@ -pub mod common; +macro_rules! syscall_mod { + ($($mod_name: ident);*) => { + $( + pub use $mod_name::$mod_name; + mod $mod_name; + )* + } +} #[cfg(unix)] pub use unix::*; diff --git a/core/src/syscall/unix/connect.rs b/core/src/syscall/unix/connect.rs index 6c33b2bb..3abd7c98 100644 --- a/core/src/syscall/unix/connect.rs +++ b/core/src/syscall/unix/connect.rs @@ -1,6 +1,6 @@ use crate::common::now; use crate::net::EventLoops; -use crate::syscall::common::{is_blocking, reset_errno, send_time_limit, set_blocking, set_errno, set_non_blocking}; +use crate::syscall::{is_blocking, reset_errno, send_time_limit, set_blocking, set_errno, set_non_blocking}; use libc::{sockaddr, socklen_t}; use once_cell::sync::Lazy; use std::ffi::{c_int, c_void}; diff --git a/core/src/syscall/unix/mod.rs b/core/src/syscall/unix/mod.rs index 5a250f33..da9c97aa 100644 --- a/core/src/syscall/unix/mod.rs +++ b/core/src/syscall/unix/mod.rs @@ -1,4 +1,3 @@ -use crate::syscall_mod; use dashmap::DashMap; use once_cell::sync::Lazy; use std::ffi::c_int; @@ -100,7 +99,7 @@ macro_rules! impl_io_uring { if syscall_result < 0 { let errno: std::ffi::c_int = (-syscall_result).try_into() .expect("io_uring errno overflow"); - $crate::syscall::common::set_errno(errno); + $crate::syscall::set_errno(errno); syscall_result = -1; } return syscall_result; @@ -126,24 +125,24 @@ macro_rules! impl_nio_read { $fd: $fd_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let mut r = -1; while left_time > 0 { r = self.inner.$syscall(fn_ptr, $fd, $($arg, )*); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); break; } let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -158,7 +157,7 @@ macro_rules! impl_nio_read { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -184,12 +183,12 @@ macro_rules! impl_nio_read_buf { $len: $len_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let mut received = 0; let mut r = -1; while received < $len && left_time > 0 { @@ -201,7 +200,7 @@ macro_rules! impl_nio_read_buf { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); received += r as size_t; if received >= $len || r == 0 { r = received as ssize_t; @@ -212,7 +211,7 @@ macro_rules! impl_nio_read_buf { if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -228,7 +227,7 @@ macro_rules! impl_nio_read_buf { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -254,12 +253,12 @@ macro_rules! impl_nio_read_iovec { $iovcnt: $iovcnt_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let vec = unsafe { Vec::from_raw_parts( $iov.cast_mut(), @@ -302,11 +301,11 @@ macro_rules! impl_nio_read_iovec { r = received as ssize_t; std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } else if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); received += r as usize; if received >= length { r = received as ssize_t; @@ -318,7 +317,7 @@ macro_rules! impl_nio_read_iovec { if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -329,14 +328,14 @@ macro_rules! impl_nio_read_iovec { r = received as ssize_t; std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } } else if error_kind != std::io::ErrorKind::Interrupted { std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } @@ -347,7 +346,7 @@ macro_rules! impl_nio_read_iovec { } std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -373,12 +372,12 @@ macro_rules! impl_nio_write_buf { $len: $len_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::send_time_limit($fd); + let mut left_time = $crate::syscall::send_time_limit($fd); let mut sent = 0; let mut r = -1; while sent < $len && left_time > 0 { @@ -390,7 +389,7 @@ macro_rules! impl_nio_write_buf { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); sent += r as size_t; if sent >= $len { r = sent as ssize_t; @@ -401,7 +400,7 @@ macro_rules! impl_nio_write_buf { if error_kind == std::io::ErrorKind::WouldBlock { //wait write event left_time = start_time - .saturating_add($crate::syscall::common::send_time_limit($fd)) + .saturating_add($crate::syscall::send_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -417,7 +416,7 @@ macro_rules! impl_nio_write_buf { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -443,12 +442,12 @@ macro_rules! impl_nio_write_iovec { $iovcnt: $iovcnt_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::send_time_limit($fd); + let mut left_time = $crate::syscall::send_time_limit($fd); let vec = unsafe { Vec::from_raw_parts( $iov.cast_mut(), @@ -488,7 +487,7 @@ macro_rules! impl_nio_write_iovec { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); sent += r as usize; if sent >= length { r = sent as ssize_t; @@ -500,7 +499,7 @@ macro_rules! impl_nio_write_iovec { if error_kind == std::io::ErrorKind::WouldBlock { //wait write event left_time = start_time - .saturating_add($crate::syscall::common::send_time_limit($fd)) + .saturating_add($crate::syscall::send_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -511,14 +510,14 @@ macro_rules! impl_nio_write_iovec { r = sent as ssize_t; std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } } else if error_kind != std::io::ErrorKind::Interrupted { std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } @@ -529,7 +528,7 @@ macro_rules! impl_nio_write_iovec { } std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -641,6 +640,10 @@ extern "C" { fn errno_location() -> *mut c_int; } +pub extern "C" fn reset_errno() { + set_errno(0); +} + pub extern "C" fn set_errno(errno: c_int) { unsafe { errno_location().write(errno) } } diff --git a/core/src/syscall/unix/nanosleep.rs b/core/src/syscall/unix/nanosleep.rs index 35d6d91b..15f402d6 100644 --- a/core/src/syscall/unix/nanosleep.rs +++ b/core/src/syscall/unix/nanosleep.rs @@ -1,5 +1,5 @@ use crate::net::EventLoops; -use crate::syscall::common::{reset_errno, set_errno}; +use crate::syscall::{reset_errno, set_errno}; use libc::timespec; use once_cell::sync::Lazy; use std::ffi::c_int; diff --git a/core/src/syscall/unix/recvmsg.rs b/core/src/syscall/unix/recvmsg.rs index ed1381b5..2c19b697 100644 --- a/core/src/syscall/unix/recvmsg.rs +++ b/core/src/syscall/unix/recvmsg.rs @@ -1,6 +1,6 @@ use crate::common::now; use crate::net::EventLoops; -use crate::syscall::common::{is_blocking, reset_errno, set_blocking, set_non_blocking, recv_time_limit}; +use crate::syscall::{is_blocking, reset_errno, set_blocking, set_non_blocking, recv_time_limit}; use libc::{msghdr, ssize_t}; use once_cell::sync::Lazy; use std::ffi::{c_int, c_void}; diff --git a/core/src/syscall/unix/sendmsg.rs b/core/src/syscall/unix/sendmsg.rs index 788ad292..32f85112 100644 --- a/core/src/syscall/unix/sendmsg.rs +++ b/core/src/syscall/unix/sendmsg.rs @@ -1,6 +1,6 @@ use crate::common::now; use crate::net::EventLoops; -use crate::syscall::common::{is_blocking, reset_errno, set_blocking, set_non_blocking, send_time_limit}; +use crate::syscall::{is_blocking, reset_errno, set_blocking, set_non_blocking, send_time_limit}; use libc::{msghdr, ssize_t}; use once_cell::sync::Lazy; use std::ffi::{c_int, c_void}; diff --git a/core/src/syscall/unix/shutdown.rs b/core/src/syscall/unix/shutdown.rs index a2e86f49..47a188f4 100644 --- a/core/src/syscall/unix/shutdown.rs +++ b/core/src/syscall/unix/shutdown.rs @@ -1,5 +1,5 @@ use crate::net::EventLoops; -use crate::syscall::common::set_errno; +use crate::syscall::set_errno; use once_cell::sync::Lazy; use std::ffi::c_int; diff --git a/core/src/syscall/unix/sleep.rs b/core/src/syscall/unix/sleep.rs index 32b8d525..2fb2c7ce 100644 --- a/core/src/syscall/unix/sleep.rs +++ b/core/src/syscall/unix/sleep.rs @@ -1,5 +1,5 @@ use crate::net::EventLoops; -use crate::syscall::common::reset_errno; +use crate::syscall::reset_errno; use once_cell::sync::Lazy; use std::ffi::c_uint; use std::time::Duration; diff --git a/core/src/syscall/unix/usleep.rs b/core/src/syscall/unix/usleep.rs index d729d86e..a6819a8f 100644 --- a/core/src/syscall/unix/usleep.rs +++ b/core/src/syscall/unix/usleep.rs @@ -1,5 +1,5 @@ use crate::net::EventLoops; -use crate::syscall::common::reset_errno; +use crate::syscall::reset_errno; use once_cell::sync::Lazy; use std::ffi::{c_int, c_uint}; use std::time::Duration; diff --git a/core/src/syscall/windows/WaitOnAddress.rs b/core/src/syscall/windows/WaitOnAddress.rs index bbf97c6a..f998926d 100644 --- a/core/src/syscall/windows/WaitOnAddress.rs +++ b/core/src/syscall/windows/WaitOnAddress.rs @@ -4,7 +4,7 @@ use once_cell::sync::Lazy; use windows_sys::Win32::Foundation::{BOOL, ERROR_TIMEOUT, FALSE, TRUE}; use crate::common::{get_timeout_time, now}; use crate::net::EventLoops; -use crate::syscall::common::reset_errno; +use crate::syscall::reset_errno; use crate::syscall::set_errno; #[must_use] diff --git a/core/src/syscall/windows/connect.rs b/core/src/syscall/windows/connect.rs index b70a075e..0d25ebb8 100644 --- a/core/src/syscall/windows/connect.rs +++ b/core/src/syscall/windows/connect.rs @@ -1,6 +1,6 @@ use crate::common::now; use crate::net::EventLoops; -use crate::syscall::common::{is_blocking, reset_errno, set_blocking, set_errno, set_non_blocking, send_time_limit}; +use crate::syscall::{is_blocking, reset_errno, set_blocking, set_errno, set_non_blocking, send_time_limit}; use once_cell::sync::Lazy; use std::ffi::c_int; use std::io::Error; diff --git a/core/src/syscall/windows/mod.rs b/core/src/syscall/windows/mod.rs index 539c79cf..9a7b4344 100644 --- a/core/src/syscall/windows/mod.rs +++ b/core/src/syscall/windows/mod.rs @@ -1,4 +1,3 @@ -use crate::syscall_mod; use dashmap::{DashMap, DashSet}; use once_cell::sync::Lazy; use std::ffi::c_int; @@ -58,24 +57,24 @@ macro_rules! impl_nio_read { $fd: $fd_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let mut r = 0; while left_time > 0 { r = self.inner.$syscall(fn_ptr, $fd, $($arg, )*); if r != -1 as _ { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); break; } let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -90,7 +89,7 @@ macro_rules! impl_nio_read { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -116,12 +115,12 @@ macro_rules! impl_nio_read_buf { $len: $len_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let mut received = 0; let mut r = -1; while received < $len && left_time > 0 { @@ -133,7 +132,7 @@ macro_rules! impl_nio_read_buf { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); received += r; if received >= $len || r == 0 { r = received; @@ -144,7 +143,7 @@ macro_rules! impl_nio_read_buf { if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -160,7 +159,7 @@ macro_rules! impl_nio_read_buf { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -186,12 +185,12 @@ macro_rules! impl_nio_read_iovec { $iovcnt: $iovcnt_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let mut left_time = $crate::syscall::recv_time_limit($fd); let vec = unsafe { Vec::from_raw_parts( $iov.cast_mut(), @@ -234,11 +233,11 @@ macro_rules! impl_nio_read_iovec { r = received.try_into().expect("overflow"); std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } else if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); received += r as usize; if received >= length { r = received.try_into().expect("overflow"); @@ -250,7 +249,7 @@ macro_rules! impl_nio_read_iovec { if error_kind == std::io::ErrorKind::WouldBlock { //wait read event left_time = start_time - .saturating_add($crate::syscall::common::recv_time_limit($fd)) + .saturating_add($crate::syscall::recv_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -261,14 +260,14 @@ macro_rules! impl_nio_read_iovec { r = received.try_into().expect("overflow"); std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } } else if error_kind != std::io::ErrorKind::Interrupted { std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } @@ -279,7 +278,7 @@ macro_rules! impl_nio_read_iovec { } std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -305,12 +304,12 @@ macro_rules! impl_nio_write_buf { $len: $len_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::send_time_limit($fd); + let mut left_time = $crate::syscall::send_time_limit($fd); let mut sent = 0; let mut r = -1; while sent < $len && left_time > 0 { @@ -322,7 +321,7 @@ macro_rules! impl_nio_write_buf { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); sent += r; if sent >= $len { r = sent; @@ -333,7 +332,7 @@ macro_rules! impl_nio_write_buf { if error_kind == std::io::ErrorKind::WouldBlock { //wait write event left_time = start_time - .saturating_add($crate::syscall::common::send_time_limit($fd)) + .saturating_add($crate::syscall::send_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -349,7 +348,7 @@ macro_rules! impl_nio_write_buf { } } if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -375,12 +374,12 @@ macro_rules! impl_nio_write_iovec { $iovcnt: $iovcnt_type, $($arg: $arg_type),* ) -> $result { - let blocking = $crate::syscall::common::is_blocking($fd); + let blocking = $crate::syscall::is_blocking($fd); if blocking { - $crate::syscall::common::set_non_blocking($fd); + $crate::syscall::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut left_time = $crate::syscall::common::send_time_limit($fd); + let mut left_time = $crate::syscall::send_time_limit($fd); let vec = unsafe { Vec::from_raw_parts( $iov.cast_mut(), @@ -420,7 +419,7 @@ macro_rules! impl_nio_write_iovec { $($arg, )* ); if r != -1 { - $crate::syscall::common::reset_errno(); + $crate::syscall::reset_errno(); sent += r as usize; if sent >= length { r = sent.try_into().expect("overflow"); @@ -432,7 +431,7 @@ macro_rules! impl_nio_write_iovec { if error_kind == std::io::ErrorKind::WouldBlock { //wait write event left_time = start_time - .saturating_add($crate::syscall::common::send_time_limit($fd)) + .saturating_add($crate::syscall::send_time_limit($fd)) .saturating_sub($crate::common::now()); let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); @@ -443,14 +442,14 @@ macro_rules! impl_nio_write_iovec { r = sent.try_into().expect("overflow"); std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } } else if error_kind != std::io::ErrorKind::Interrupted { std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } return r; } @@ -461,7 +460,7 @@ macro_rules! impl_nio_write_iovec { } std::mem::forget(vec); if blocking { - $crate::syscall::common::set_blocking($fd); + $crate::syscall::set_blocking($fd); } r } @@ -518,6 +517,10 @@ static SEND_TIME_LIMIT: Lazy> = Lazy::new(Default::default) static RECV_TIME_LIMIT: Lazy> = Lazy::new(Default::default); +pub extern "system" fn reset_errno() { + set_errno(0); +} + pub extern "system" fn set_errno(errno: windows_sys::Win32::Foundation::WIN32_ERROR) { unsafe { windows_sys::Win32::Foundation::SetLastError(errno) } } diff --git a/core/src/syscall/windows/shutdown.rs b/core/src/syscall/windows/shutdown.rs index a10a01f2..6d50d46f 100644 --- a/core/src/syscall/windows/shutdown.rs +++ b/core/src/syscall/windows/shutdown.rs @@ -1,5 +1,5 @@ use crate::net::EventLoops; -use crate::syscall::common::set_errno; +use crate::syscall::set_errno; use once_cell::sync::Lazy; use std::ffi::c_int; use windows_sys::Win32::Networking::WinSock::{SOCKET, WINSOCK_SHUTDOWN_HOW};