@@ -131,8 +131,11 @@ macro_rules! impl_nio_read {
131131 $crate:: syscall:: common:: set_non_blocking( $fd) ;
132132 }
133133 let start_time = $crate:: common:: now( ) ;
134- let mut r;
135- loop {
134+ let mut left_time = start_time
135+ . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
136+ . saturating_sub( start_time) ;
137+ let mut r = -1 ;
138+ while left_time > 0 {
136139 r = self . inner. $syscall( fn_ptr, $fd, $( $arg, ) * ) ;
137140 if r != -1 {
138141 $crate:: syscall:: common:: reset_errno( ) ;
@@ -141,9 +144,10 @@ macro_rules! impl_nio_read {
141144 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
142145 if error_kind == std:: io:: ErrorKind :: WouldBlock {
143146 //wait read event
144- let wait_time = std :: time :: Duration :: from_nanos ( start_time
147+ left_time = start_time
145148 . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
146- . saturating_sub( $crate:: common:: now( ) ) )
149+ . saturating_sub( $crate:: common:: now( ) ) ;
150+ let wait_time = std:: time:: Duration :: from_nanos( left_time)
147151 . min( $crate:: common:: constants:: SLICE ) ;
148152 if $crate:: net:: EventLoops :: wait_read_event(
149153 $fd,
@@ -187,9 +191,12 @@ macro_rules! impl_nio_read_buf {
187191 $crate:: syscall:: common:: set_non_blocking( $fd) ;
188192 }
189193 let start_time = $crate:: common:: now( ) ;
194+ let mut left_time = start_time
195+ . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
196+ . saturating_sub( start_time) ;
190197 let mut received = 0 ;
191198 let mut r = 0 ;
192- while received < $len {
199+ while received < $len && left_time > 0 {
193200 r = self . inner. $syscall(
194201 fn_ptr,
195202 $fd,
@@ -208,9 +215,10 @@ macro_rules! impl_nio_read_buf {
208215 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
209216 if error_kind == std:: io:: ErrorKind :: WouldBlock {
210217 //wait read event
211- let wait_time = std :: time :: Duration :: from_nanos ( start_time
218+ left_time = start_time
212219 . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
213- . saturating_sub( $crate:: common:: now( ) ) )
220+ . saturating_sub( $crate:: common:: now( ) ) ;
221+ let wait_time = std:: time:: Duration :: from_nanos( left_time)
214222 . min( $crate:: common:: constants:: SLICE ) ;
215223 if $crate:: net:: EventLoops :: wait_read_event(
216224 $fd,
@@ -253,8 +261,11 @@ macro_rules! impl_nio_read_iovec {
253261 if blocking {
254262 $crate:: syscall:: common:: set_non_blocking( $fd) ;
255263 }
256- let vec = unsafe { Vec :: from_raw_parts( $iov. cast_mut( ) , $iovcnt as usize , $iovcnt as usize ) } ;
257264 let start_time = $crate:: common:: now( ) ;
265+ let mut left_time = start_time
266+ . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
267+ . saturating_sub( start_time) ;
268+ let vec = unsafe { Vec :: from_raw_parts( $iov. cast_mut( ) , $iovcnt as usize , $iovcnt as usize ) } ;
258269 let mut length = 0 ;
259270 let mut received = 0usize ;
260271 let mut r = 0 ;
@@ -270,7 +281,7 @@ macro_rules! impl_nio_read_iovec {
270281 for i in vec. iter( ) . skip( index) {
271282 arg. push( * i) ;
272283 }
273- while received < length {
284+ while received < length && left_time > 0 {
274285 if 0 != offset {
275286 arg[ 0 ] = libc:: iovec {
276287 iov_base: ( arg[ 0 ] . iov_base as usize + offset) as * mut std:: ffi:: c_void,
@@ -304,9 +315,10 @@ macro_rules! impl_nio_read_iovec {
304315 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
305316 if error_kind == std:: io:: ErrorKind :: WouldBlock {
306317 //wait read event
307- let wait_time = std :: time :: Duration :: from_nanos ( start_time
318+ left_time = start_time
308319 . saturating_add( $crate:: syscall:: common:: recv_time_limit( $fd) )
309- . saturating_sub( $crate:: common:: now( ) ) )
320+ . saturating_sub( $crate:: common:: now( ) ) ;
321+ let wait_time = std:: time:: Duration :: from_nanos( left_time)
310322 . min( $crate:: common:: constants:: SLICE ) ;
311323 if $crate:: net:: EventLoops :: wait_read_event(
312324 $fd,
@@ -363,9 +375,12 @@ macro_rules! impl_nio_write_buf {
363375 $crate:: syscall:: common:: set_non_blocking( $fd) ;
364376 }
365377 let start_time = $crate:: common:: now( ) ;
378+ let mut left_time = start_time
379+ . saturating_add( $crate:: syscall:: common:: send_time_limit( $fd) )
380+ . saturating_sub( start_time) ;
366381 let mut sent = 0 ;
367382 let mut r = 0 ;
368- while sent < $len {
383+ while sent < $len && left_time > 0 {
369384 r = self . inner. $syscall(
370385 fn_ptr,
371386 $fd,
@@ -384,9 +399,10 @@ macro_rules! impl_nio_write_buf {
384399 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
385400 if error_kind == std:: io:: ErrorKind :: WouldBlock {
386401 //wait write event
387- let wait_time = std :: time :: Duration :: from_nanos ( start_time
402+ left_time = start_time
388403 . saturating_add( $crate:: syscall:: common:: send_time_limit( $fd) )
389- . saturating_sub( $crate:: common:: now( ) ) )
404+ . saturating_sub( $crate:: common:: now( ) ) ;
405+ let wait_time = std:: time:: Duration :: from_nanos( left_time)
390406 . min( $crate:: common:: constants:: SLICE ) ;
391407 if $crate:: net:: EventLoops :: wait_write_event(
392408 $fd,
@@ -431,8 +447,11 @@ macro_rules! impl_nio_write_iovec {
431447 if blocking {
432448 $crate:: syscall:: common:: set_non_blocking( $fd) ;
433449 }
434- let vec = unsafe { Vec :: from_raw_parts( $iov. cast_mut( ) , $iovcnt as usize , $iovcnt as usize ) } ;
435450 let start_time = $crate:: common:: now( ) ;
451+ let mut left_time = start_time
452+ . saturating_add( $crate:: syscall:: common:: send_time_limit( $fd) )
453+ . saturating_sub( start_time) ;
454+ let vec = unsafe { Vec :: from_raw_parts( $iov. cast_mut( ) , $iovcnt as usize , $iovcnt as usize ) } ;
436455 let mut length = 0 ;
437456 let mut sent = 0usize ;
438457 let mut r = 0 ;
@@ -448,7 +467,7 @@ macro_rules! impl_nio_write_iovec {
448467 for i in vec. iter( ) . skip( index) {
449468 arg. push( * i) ;
450469 }
451- while sent < length {
470+ while sent < length && left_time > 0 {
452471 if 0 != offset {
453472 arg[ 0 ] = libc:: iovec {
454473 iov_base: ( arg[ 0 ] . iov_base as usize + offset) as * mut std:: ffi:: c_void,
@@ -476,9 +495,10 @@ macro_rules! impl_nio_write_iovec {
476495 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
477496 if error_kind == std:: io:: ErrorKind :: WouldBlock {
478497 //wait write event
479- let wait_time = std :: time :: Duration :: from_nanos ( start_time
498+ left_time = start_time
480499 . saturating_add( $crate:: syscall:: common:: send_time_limit( $fd) )
481- . saturating_sub( $crate:: common:: now( ) ) )
500+ . saturating_sub( $crate:: common:: now( ) ) ;
501+ let wait_time = std:: time:: Duration :: from_nanos( left_time)
482502 . min( $crate:: common:: constants:: SLICE ) ;
483503 if $crate:: net:: EventLoops :: wait_write_event(
484504 $fd,
@@ -670,16 +690,21 @@ pub extern "C" fn send_time_limit(fd: c_int) -> u64 {
670690 || unsafe {
671691 let mut tv: libc:: timeval = std:: mem:: zeroed ( ) ;
672692 let mut len = size_of :: < libc:: timeval > ( ) as libc:: socklen_t ;
673- assert_eq ! (
674- 0 ,
675- libc:: getsockopt(
676- fd,
677- libc:: SOL_SOCKET ,
678- libc:: SO_SNDTIMEO ,
679- std:: ptr:: from_mut( & mut tv) . cast( ) ,
680- & mut len,
681- )
682- ) ;
693+ if libc:: getsockopt (
694+ fd,
695+ libc:: SOL_SOCKET ,
696+ libc:: SO_SNDTIMEO ,
697+ std:: ptr:: from_mut ( & mut tv) . cast ( ) ,
698+ & mut len,
699+ ) == -1
700+ {
701+ let error = std:: io:: Error :: last_os_error ( ) ;
702+ if Some ( libc:: ENOTSOCK ) == error. raw_os_error ( ) {
703+ // not a socket
704+ return u64:: MAX ;
705+ }
706+ panic ! ( "getsockopt failed: {}" , error) ;
707+ }
683708 let mut time_limit = ( tv. tv_sec as u64 )
684709 . saturating_mul ( 1_000_000_000 )
685710 . saturating_add ( ( tv. tv_usec as u64 ) . saturating_mul ( 1_000 ) ) ;
@@ -700,16 +725,21 @@ pub extern "C" fn recv_time_limit(fd: c_int) -> u64 {
700725 || unsafe {
701726 let mut tv: libc:: timeval = std:: mem:: zeroed ( ) ;
702727 let mut len = size_of :: < libc:: timeval > ( ) as libc:: socklen_t ;
703- assert_eq ! (
704- 0 ,
705- libc:: getsockopt(
706- fd,
707- libc:: SOL_SOCKET ,
708- libc:: SO_RCVTIMEO ,
709- std:: ptr:: from_mut( & mut tv) . cast( ) ,
710- & mut len,
711- )
712- ) ;
728+ if libc:: getsockopt (
729+ fd,
730+ libc:: SOL_SOCKET ,
731+ libc:: SO_RCVTIMEO ,
732+ std:: ptr:: from_mut ( & mut tv) . cast ( ) ,
733+ & mut len,
734+ ) == -1
735+ {
736+ let error = std:: io:: Error :: last_os_error ( ) ;
737+ if Some ( libc:: ENOTSOCK ) == error. raw_os_error ( ) {
738+ // not a socket
739+ return u64:: MAX ;
740+ }
741+ panic ! ( "getsockopt failed: {}" , error) ;
742+ }
713743 let mut time_limit = ( tv. tv_sec as u64 )
714744 . saturating_mul ( 1_000_000_000 )
715745 . saturating_add ( ( tv. tv_usec as u64 ) . saturating_mul ( 1_000 ) ) ;
0 commit comments