Skip to content

Commit 77c5b01

Browse files
authored
Retry pselect on EINTR (#344)
The Go runtime may send signals to pause goroutines and these signals can interrupt pselect6. When this happens, the syscall returns EINTR. This change handles that case by retrying pselect6 on EINTR. The same approach is used by the mdlayher/socket library for sendmsg/recvmsg operations: https://github.com/mdlayher/socket/blob/8e6558649a7bd11ca1bd2b82c45fc96dee4dc11d/conn.go#L871.
1 parent 35f95ac commit 77c5b01

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

socket.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,20 @@ func (cc *Conn) isReadReady(conn *netlink.Conn) (bool, error) {
2929
readfds.Set(int(fd))
3030

3131
ts := &unix.Timespec{} // zero timeout: immediate return
32-
n, opErr = unix.Pselect(int(fd)+1, &readfds, nil, nil, ts, nil)
32+
for {
33+
n, opErr = unix.Pselect(int(fd)+1, &readfds, nil, nil, ts, nil)
34+
if opErr != unix.EINTR {
35+
break
36+
}
37+
}
3338
})
3439
if err != nil {
3540
return false, err
3641
}
3742

38-
return n > 0, opErr
43+
if opErr != nil {
44+
return false, fmt.Errorf("pselect6: %w", opErr)
45+
}
46+
47+
return n > 0, nil
3948
}

0 commit comments

Comments
 (0)