diff --git a/core/src/syscall/unix/connect.rs b/core/src/syscall/unix/connect.rs index a683737c..6c33b2bb 100644 --- a/core/src/syscall/unix/connect.rs +++ b/core/src/syscall/unix/connect.rs @@ -63,11 +63,9 @@ impl ConnectSyscall for NioConnectSyscall { set_non_blocking(fd); } let start_time = now(); + let mut left_time = send_time_limit(fd); let mut r = self.inner.connect(fn_ptr, fd, address, len); - while start_time - .saturating_add(send_time_limit(fd)) - .saturating_sub(now()) > 0 - { + while left_time > 0 { if r == 0 { reset_errno(); break; @@ -75,7 +73,12 @@ impl ConnectSyscall for NioConnectSyscall { let errno = Error::last_os_error().raw_os_error(); if errno == Some(libc::EINPROGRESS) || errno == Some(libc::EALREADY) || errno == Some(libc::EWOULDBLOCK) { //阻塞,直到写事件发生 - if EventLoops::wait_write_event(fd, Some(crate::common::constants::SLICE)).is_err() + left_time = start_time + .saturating_add(send_time_limit(fd)) + .saturating_sub(now()); + let wait_time = std::time::Duration::from_nanos(left_time) + .min(crate::common::constants::SLICE); + if EventLoops::wait_write_event(fd, Some(wait_time)).is_err() { break; } diff --git a/core/src/syscall/unix/mod.rs b/core/src/syscall/unix/mod.rs index 53452ee5..2339ffa5 100644 --- a/core/src/syscall/unix/mod.rs +++ b/core/src/syscall/unix/mod.rs @@ -33,7 +33,7 @@ macro_rules! impl_facade { $crate::error!("{} change to running state failed !", co.name()); } } - $crate::info!("exit syscall {} {:?}", syscall, r); + $crate::info!("exit syscall {} {:?} {}", syscall, r, std::io::Error::last_os_error()); r } } @@ -259,7 +259,13 @@ macro_rules! impl_nio_read_iovec { } let start_time = $crate::common::now(); let mut left_time = $crate::syscall::common::recv_time_limit($fd); - let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; + let vec = unsafe { + Vec::from_raw_parts( + $iov.cast_mut(), + $iovcnt as usize, + $iovcnt as usize + ) + }; let mut length = 0; let mut received = 0usize; let mut r = 0; @@ -441,7 +447,13 @@ macro_rules! impl_nio_write_iovec { } let start_time = $crate::common::now(); let mut left_time = $crate::syscall::common::send_time_limit($fd); - let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; + let vec = unsafe { + Vec::from_raw_parts( + $iov.cast_mut(), + $iovcnt as usize, + $iovcnt as usize + ) + }; let mut length = 0; let mut sent = 0usize; let mut r = 0; diff --git a/core/src/syscall/windows/connect.rs b/core/src/syscall/windows/connect.rs index a074cbf3..b70a075e 100644 --- a/core/src/syscall/windows/connect.rs +++ b/core/src/syscall/windows/connect.rs @@ -1,5 +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}; +use crate::syscall::common::{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; @@ -49,8 +50,10 @@ impl ConnectSyscall for NioConnectSyscall { if blocking { set_non_blocking(fd); } + let start_time = now(); + let mut left_time = send_time_limit(fd); let mut r = self.inner.connect(fn_ptr, fd, address, len); - loop { + while left_time > 0 { if r == 0 { reset_errno(); break; @@ -58,9 +61,14 @@ impl ConnectSyscall for NioConnectSyscall { let errno = Error::last_os_error().raw_os_error(); if errno == Some(WSAEINPROGRESS) || errno == Some(WSAEALREADY) || errno == Some(WSAEWOULDBLOCK) { //阻塞,直到写事件发生 + left_time = start_time + .saturating_add(send_time_limit(fd)) + .saturating_sub(now()); + let wait_time = std::time::Duration::from_nanos(left_time) + .min(crate::common::constants::SLICE); if EventLoops::wait_write_event( fd as _, - Some(crate::common::constants::SLICE) + Some(wait_time) ).is_err() { break; } diff --git a/core/src/syscall/windows/mod.rs b/core/src/syscall/windows/mod.rs index f1f0269a..52febbe5 100644 --- a/core/src/syscall/windows/mod.rs +++ b/core/src/syscall/windows/mod.rs @@ -36,7 +36,7 @@ macro_rules! impl_facade { $crate::error!("{} change to running state failed !", co.name()); } } - $crate::info!("exit syscall {} {:?}", syscall, r); + $crate::info!("exit syscall {} {:?} {}", syscall, r, std::io::Error::last_os_error()); r } } @@ -63,8 +63,9 @@ macro_rules! impl_nio_read { $crate::syscall::common::set_non_blocking($fd); } let start_time = $crate::common::now(); - let mut r; - loop { + let mut left_time = $crate::syscall::common::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(); @@ -73,9 +74,10 @@ macro_rules! impl_nio_read { let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait read event - let wait_time = std::time::Duration::from_nanos(start_time + left_time = start_time .saturating_add($crate::syscall::common::recv_time_limit($fd)) - .saturating_sub($crate::common::now())) + .saturating_sub($crate::common::now()); + let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); if $crate::net::EventLoops::wait_read_event( $fd as _, @@ -119,9 +121,10 @@ macro_rules! impl_nio_read_buf { $crate::syscall::common::set_non_blocking($fd); } let start_time = $crate::common::now(); + let mut left_time = $crate::syscall::common::recv_time_limit($fd); let mut received = 0; let mut r = 0; - while received < $len { + while received < $len && left_time > 0 { r = self.inner.$syscall( fn_ptr, $fd, @@ -140,9 +143,10 @@ macro_rules! impl_nio_read_buf { let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait read event - let wait_time = std::time::Duration::from_nanos(start_time + left_time = start_time .saturating_add($crate::syscall::common::recv_time_limit($fd)) - .saturating_sub($crate::common::now())) + .saturating_sub($crate::common::now()); + let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); if $crate::net::EventLoops::wait_read_event( $fd as _, @@ -187,8 +191,15 @@ macro_rules! impl_nio_read_iovec { if blocking { $crate::syscall::common::set_non_blocking($fd); } - let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; let start_time = $crate::common::now(); + let mut left_time = $crate::syscall::common::recv_time_limit($fd); + let vec = unsafe { + Vec::from_raw_parts( + $iov.cast_mut(), + $iovcnt as usize, + $iovcnt as usize + ) + }; let mut length = 0; let mut received = 0usize; let mut r = 0; @@ -204,7 +215,7 @@ macro_rules! impl_nio_read_iovec { for i in vec.iter().skip(index) { arg.push(*i); } - while received < length { + while received < length && left_time > 0 { if 0 != offset { arg[0] = windows_sys::Win32::Networking::WinSock::WSABUF { buf: (arg[0].buf as usize + offset) as windows_sys::core::PSTR, @@ -238,9 +249,10 @@ macro_rules! impl_nio_read_iovec { let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait read event - let wait_time = std::time::Duration::from_nanos(start_time + left_time = start_time .saturating_add($crate::syscall::common::recv_time_limit($fd)) - .saturating_sub($crate::common::now())) + .saturating_sub($crate::common::now()); + let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); if $crate::net::EventLoops::wait_read_event( $fd as _, @@ -297,9 +309,10 @@ macro_rules! impl_nio_write_buf { $crate::syscall::common::set_non_blocking($fd); } let start_time = $crate::common::now(); + let mut left_time = $crate::syscall::common::send_time_limit($fd); let mut sent = 0; let mut r = 0; - while sent < $len { + while sent < $len && left_time > 0 { r = self.inner.$syscall( fn_ptr, $fd, @@ -318,9 +331,10 @@ macro_rules! impl_nio_write_buf { let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait write event - let wait_time = std::time::Duration::from_nanos(start_time + left_time = start_time .saturating_add($crate::syscall::common::send_time_limit($fd)) - .saturating_sub($crate::common::now())) + .saturating_sub($crate::common::now()); + let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); if $crate::net::EventLoops::wait_write_event( $fd as _, @@ -365,8 +379,15 @@ macro_rules! impl_nio_write_iovec { if blocking { $crate::syscall::common::set_non_blocking($fd); } - let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; let start_time = $crate::common::now(); + let mut left_time = $crate::syscall::common::send_time_limit($fd); + let vec = unsafe { + Vec::from_raw_parts( + $iov.cast_mut(), + $iovcnt as usize, + $iovcnt as usize + ) + }; let mut length = 0; let mut sent = 0usize; let mut r = 0; @@ -382,7 +403,7 @@ macro_rules! impl_nio_write_iovec { for i in vec.iter().skip(index) { arg.push(*i); } - while sent < length { + while sent < length && left_time > 0 { if 0 != offset { arg[0] = windows_sys::Win32::Networking::WinSock::WSABUF { buf: (arg[0].buf as usize + offset) as windows_sys::core::PSTR, @@ -410,9 +431,10 @@ macro_rules! impl_nio_write_iovec { let error_kind = std::io::Error::last_os_error().kind(); if error_kind == std::io::ErrorKind::WouldBlock { //wait write event - let wait_time = std::time::Duration::from_nanos(start_time + left_time = start_time .saturating_add($crate::syscall::common::send_time_limit($fd)) - .saturating_sub($crate::common::now())) + .saturating_sub($crate::common::now()); + let wait_time = std::time::Duration::from_nanos(left_time) .min($crate::common::constants::SLICE); if $crate::net::EventLoops::wait_write_event( $fd as _,