@@ -533,8 +533,9 @@ macro_rules! impl_nio_read_iovec {
533533 let mut received = 0usize ;
534534 let mut r = windows_sys:: Win32 :: Networking :: WinSock :: SOCKET_ERROR ;
535535 let mut index = 0 ;
536- ' outer: for iovec in & vec {
537- let mut offset = received. saturating_sub( length) ;
536+ for iovec in & vec {
537+ let stage = length;
538+ let mut offset = received. saturating_sub( stage) ;
538539 length += iovec. len as usize ;
539540 if received > length {
540541 index += 1 ;
@@ -545,6 +546,7 @@ macro_rules! impl_nio_read_iovec {
545546 arg. push( * i) ;
546547 }
547548 while received < length && left_time > 0 {
549+ // Assuming len is 4, but only 1 is read, at this point we should continue trying to fill the current WSABUF
548550 if 0 != offset {
549551 arg[ 0 ] = windows_sys:: Win32 :: Networking :: WinSock :: WSABUF {
550552 buf: ( arg[ 0 ] . buf as usize + offset) as windows_sys:: core:: PSTR ,
@@ -561,14 +563,24 @@ macro_rules! impl_nio_read_iovec {
561563 $recvd,
562564 $( $arg, ) *
563565 ) ;
564- if r != windows_sys:: Win32 :: Networking :: WinSock :: SOCKET_ERROR {
565- $crate:: syscall:: reset_errno( ) ;
566- // WSARecv returns 0 on success; actual byte count is in *$recvd
567- received += unsafe { * $recvd } as usize ;
566+ if unsafe { * $recvd == 0 } {
568567 r = 0 ;
569568 unsafe { $recvd. write( received. try_into( ) . expect( "overflow" ) ) } ;
570- // WSARecv returns as soon as any data is received
571- break ' outer;
569+ std:: mem:: forget( vec) ;
570+ if blocking {
571+ $crate:: syscall:: set_blocking( $fd) ;
572+ }
573+ // as success
574+ return r;
575+ } else if r != windows_sys:: Win32 :: Networking :: WinSock :: SOCKET_ERROR {
576+ $crate:: syscall:: reset_errno( ) ;
577+ received += unsafe { usize :: try_from( * $recvd) . expect( "overflow" ) } ;
578+ if received >= length {
579+ r = 0 ;
580+ unsafe { $recvd. write( received. try_into( ) . expect( "overflow" ) ) } ;
581+ break ;
582+ }
583+ offset = received. saturating_sub( stage) ;
572584 }
573585 let error_kind = std:: io:: Error :: last_os_error( ) . kind( ) ;
574586 if error_kind == std:: io:: ErrorKind :: WouldBlock {
@@ -802,8 +814,7 @@ macro_rules! impl_nio_write_iovec {
802814 ) ;
803815 if r != windows_sys:: Win32 :: Networking :: WinSock :: SOCKET_ERROR {
804816 $crate:: syscall:: reset_errno( ) ;
805- // WSASend returns 0 on success; actual byte count is in *$sent
806- sent += unsafe { * $sent } as usize ;
817+ sent += unsafe { usize :: try_from( * $sent) . expect( "overflow" ) } ;
807818 if sent >= length {
808819 r = 0 ;
809820 unsafe { $sent. write( sent. try_into( ) . expect( "overflow" ) ) } ;
0 commit comments