mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix bug in RecvMMsgDispatcher.
Fixed a bug introduced in the following commit: https://github.com/google/gvisor/commit/979d6e7d77b17e94defc29515180cc75d3560383 The commit introduced a bug which causes the recvmmsg dispatcher to never exit as BlockingPoll is now called with two fds and poll will not return an error anymore if one of the FD is closed. We need to explicitly check the events for each FD to determine if the sentry FD is closed. ReadV dispatcher does not have the same issue as Readv does not rely on sk_err field of the underlying socket to determine if the socket is in an error state. Recvmmsg OTOH seems to get confused and always returns EAGAIN if poll() is called which queries the sk_err field and clears it. PiperOrigin-RevId: 396676135
This commit is contained in:
committed by
gVisor bot
parent
5593b8a7e6
commit
603f473ada
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
|
||||
MOVQ $0x0, R10 // sigmask parameter which isn't used here
|
||||
MOVQ $0x10f, AX // SYS_PPOLL
|
||||
SYSCALL
|
||||
CMPQ AX, $0xfffffffffffff001
|
||||
CMPQ AX, $0xfffffffffffff002
|
||||
JLS ok
|
||||
MOVQ $-1, n+24(FP)
|
||||
NEGQ AX
|
||||
|
||||
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
|
||||
MOVD $0x0, R3 // sigmask parameter which isn't used here
|
||||
MOVD $0x49, R8 // SYS_PPOLL
|
||||
SVC
|
||||
CMP $0xfffffffffffff001, R0
|
||||
CMP $0xfffffffffffff002, R0
|
||||
BLS ok
|
||||
MOVD $-1, R1
|
||||
MOVD R1, n+24(FP)
|
||||
|
||||
@@ -181,7 +181,9 @@ func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, tcpip
|
||||
if e == 0 {
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
if e != 0 && e != unix.EWOULDBLOCK {
|
||||
return 0, TranslateErrno(e)
|
||||
}
|
||||
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
|
||||
if stopped {
|
||||
return -1, nil
|
||||
@@ -204,6 +206,10 @@ func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MMsgHdr) (int, tcpi
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
if e != 0 && e != unix.EWOULDBLOCK {
|
||||
return 0, TranslateErrno(e)
|
||||
}
|
||||
|
||||
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
|
||||
if stopped {
|
||||
return -1, nil
|
||||
@@ -228,5 +234,13 @@ func BlockingPollUntilStopped(efd int, fd int, events int16) (bool, unix.Errno)
|
||||
},
|
||||
}
|
||||
_, errno := BlockingPoll(&pevents[0], len(pevents), nil)
|
||||
if errno != 0 {
|
||||
return pevents[0].Revents&unix.POLLIN != 0, errno
|
||||
}
|
||||
|
||||
if pevents[1].Revents&unix.POLLHUP != 0 || pevents[1].Revents&unix.POLLERR != 0 {
|
||||
errno = unix.ECONNRESET
|
||||
}
|
||||
|
||||
return pevents[0].Revents&unix.POLLIN != 0, errno
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user