Set blocking mode on hijacked fds for sendfile

This commit is contained in:
Laurence Withers 2019-05-10 13:21:22 +01:00
parent 21a18eced6
commit eac79eb605
1 changed files with 14 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import (
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
"github.com/lwithers/htpack/packed"
@ -194,6 +195,19 @@ func (h *Handler) sendfile(w http.ResponseWriter, data *packed.FileData) {
if err == nil {
err = buf.Flush()
}
if err == nil {
// Since we're bypassing Read / Write, there is no integration
// with Go's epoll-driven event handling for this file
// descriptor. We'll therefore get EAGAIN behaviour rather
// than blocking for Sendfile(). Work around this by setting
// the file descriptor to blocking mode; since this function
// now guarantees (via defer tcp.Close()) that the connection
// will be closed and not be passed back to Go's own event
// loop, this is safe to do.
rawsock.Control(func(outfd uintptr) {
err = syscall.SetNonblock(int(outfd), false)
})
}
if err != nil {
// error only returned if the underlying connection is broken,
// so there's no point calling sendfile