mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Deflake SendFileTest_Shutdown.
The sendfile syscall's backing doSplice contained a race with regard to blocking. If the first attempt failed with syserror.ErrWouldBlock and then the blocking file became ready before registering a waiter, we would just return the ErrWouldBlock (even if we were supposed to block). PiperOrigin-RevId: 254114432
This commit is contained in:
@@ -48,12 +48,12 @@ func doSplice(t *kernel.Task, outFile, inFile *fs.File, opts fs.SpliceOpts, nonB
|
||||
if ch == nil {
|
||||
ch = make(chan struct{}, 1)
|
||||
}
|
||||
if !inW && inFile.Readiness(EventMaskRead) == 0 && !inFile.Flags().NonBlocking {
|
||||
if !inW && !inFile.Flags().NonBlocking {
|
||||
w, _ := waiter.NewChannelEntry(ch)
|
||||
inFile.EventRegister(&w, EventMaskRead)
|
||||
defer inFile.EventUnregister(&w)
|
||||
inW = true // Registered.
|
||||
} else if !outW && outFile.Readiness(EventMaskWrite) == 0 && !outFile.Flags().NonBlocking {
|
||||
} else if !outW && !outFile.Flags().NonBlocking {
|
||||
w, _ := waiter.NewChannelEntry(ch)
|
||||
outFile.EventRegister(&w, EventMaskWrite)
|
||||
defer outFile.EventUnregister(&w)
|
||||
@@ -65,6 +65,11 @@ func doSplice(t *kernel.Task, outFile, inFile *fs.File, opts fs.SpliceOpts, nonB
|
||||
break
|
||||
}
|
||||
|
||||
if (!inW || inFile.Readiness(EventMaskRead) != 0) && (!outW || outFile.Readiness(EventMaskWrite) != 0) {
|
||||
// Something became ready, try again without blocking.
|
||||
continue
|
||||
}
|
||||
|
||||
// Block until there's data.
|
||||
if err = t.Block(ch); err != nil {
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user