Commit b09d8817 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

net: refactoring in preparation for integrated network poller

Introduce pollDesc struct, to split netFD struct into fd-related
and poller-related parts.

R=golang-dev, bradfitz, iant
CC=golang-dev
https://golang.org/cl/7762044
parent 07fb6fcd
...@@ -29,10 +29,25 @@ type pollServer struct { ...@@ -29,10 +29,25 @@ type pollServer struct {
pr, pw *os.File pr, pw *os.File
poll *pollster // low-level OS hooks poll *pollster // low-level OS hooks
sync.Mutex // controls pending and deadline sync.Mutex // controls pending and deadline
pending map[int]*netFD pending map[int]*pollDesc
deadline int64 // next deadline (nsec since 1970) deadline int64 // next deadline (nsec since 1970)
} }
// A pollDesc contains netFD state related to pollServer.
type pollDesc struct {
// immutable after Init()
pollServer *pollServer
sysfd int
cr, cw chan error
// mutable, protected by pollServer mutex
closing bool
ncr, ncw int
// mutable, safe for concurrent access
rdeadline, wdeadline deadline
}
func newPollServer() (s *pollServer, err error) { func newPollServer() (s *pollServer, err error) {
s = new(pollServer) s = new(pollServer)
if s.pr, s.pw, err = os.Pipe(); err != nil { if s.pr, s.pw, err = os.Pipe(); err != nil {
...@@ -51,7 +66,7 @@ func newPollServer() (s *pollServer, err error) { ...@@ -51,7 +66,7 @@ func newPollServer() (s *pollServer, err error) {
s.poll.Close() s.poll.Close()
goto Error goto Error
} }
s.pending = make(map[int]*netFD) s.pending = make(map[int]*pollDesc)
go s.Run() go s.Run()
return s, nil return s, nil
...@@ -67,10 +82,10 @@ Error: ...@@ -67,10 +82,10 @@ Error:
return nil, err return nil, err
} }
func (s *pollServer) AddFD(fd *netFD, mode int) error { func (s *pollServer) AddFD(pd *pollDesc, mode int) error {
s.Lock() s.Lock()
intfd := fd.sysfd intfd := pd.sysfd
if intfd < 0 || fd.closing { if intfd < 0 || pd.closing {
// fd closed underfoot // fd closed underfoot
s.Unlock() s.Unlock()
return errClosing return errClosing
...@@ -79,14 +94,14 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error { ...@@ -79,14 +94,14 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error {
var t int64 var t int64
key := intfd << 1 key := intfd << 1
if mode == 'r' { if mode == 'r' {
fd.ncr++ pd.ncr++
t = fd.rdeadline.value() t = pd.rdeadline.value()
} else { } else {
fd.ncw++ pd.ncw++
key++ key++
t = fd.wdeadline.value() t = pd.wdeadline.value()
} }
s.pending[key] = fd s.pending[key] = pd
doWakeup := false doWakeup := false
if t > 0 && (s.deadline == 0 || t < s.deadline) { if t > 0 && (s.deadline == 0 || t < s.deadline) {
s.deadline = t s.deadline = t
...@@ -96,7 +111,7 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error { ...@@ -96,7 +111,7 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error {
wake, err := s.poll.AddFD(intfd, mode, false) wake, err := s.poll.AddFD(intfd, mode, false)
s.Unlock() s.Unlock()
if err != nil { if err != nil {
return &OpError{"addfd", fd.net, fd.laddr, err} return err
} }
if wake || doWakeup { if wake || doWakeup {
s.Wakeup() s.Wakeup()
...@@ -104,25 +119,26 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error { ...@@ -104,25 +119,26 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error {
return nil return nil
} }
// Evict evicts fd from the pending list, unblocking // Evict evicts pd from the pending list, unblocking
// any I/O running on fd. The caller must have locked // any I/O running on pd. The caller must have locked
// pollserver. // pollserver.
// Return value is whether the pollServer should be woken up. // Return value is whether the pollServer should be woken up.
func (s *pollServer) Evict(fd *netFD) bool { func (s *pollServer) Evict(pd *pollDesc) bool {
pd.closing = true
doWakeup := false doWakeup := false
if s.pending[fd.sysfd<<1] == fd { if s.pending[pd.sysfd<<1] == pd {
s.WakeFD(fd, 'r', errClosing) s.WakeFD(pd, 'r', errClosing)
if s.poll.DelFD(fd.sysfd, 'r') { if s.poll.DelFD(pd.sysfd, 'r') {
doWakeup = true doWakeup = true
} }
delete(s.pending, fd.sysfd<<1) delete(s.pending, pd.sysfd<<1)
} }
if s.pending[fd.sysfd<<1|1] == fd { if s.pending[pd.sysfd<<1|1] == pd {
s.WakeFD(fd, 'w', errClosing) s.WakeFD(pd, 'w', errClosing)
if s.poll.DelFD(fd.sysfd, 'w') { if s.poll.DelFD(pd.sysfd, 'w') {
doWakeup = true doWakeup = true
} }
delete(s.pending, fd.sysfd<<1|1) delete(s.pending, pd.sysfd<<1|1)
} }
return doWakeup return doWakeup
} }
...@@ -131,7 +147,7 @@ var wakeupbuf [1]byte ...@@ -131,7 +147,7 @@ var wakeupbuf [1]byte
func (s *pollServer) Wakeup() { s.pw.Write(wakeupbuf[0:]) } func (s *pollServer) Wakeup() { s.pw.Write(wakeupbuf[0:]) }
func (s *pollServer) LookupFD(fd int, mode int) *netFD { func (s *pollServer) LookupFD(fd int, mode int) *pollDesc {
key := fd << 1 key := fd << 1
if mode == 'w' { if mode == 'w' {
key++ key++
...@@ -144,16 +160,16 @@ func (s *pollServer) LookupFD(fd int, mode int) *netFD { ...@@ -144,16 +160,16 @@ func (s *pollServer) LookupFD(fd int, mode int) *netFD {
return netfd return netfd
} }
func (s *pollServer) WakeFD(fd *netFD, mode int, err error) { func (s *pollServer) WakeFD(pd *pollDesc, mode int, err error) {
if mode == 'r' { if mode == 'r' {
for fd.ncr > 0 { for pd.ncr > 0 {
fd.ncr-- pd.ncr--
fd.cr <- err pd.cr <- err
} }
} else { } else {
for fd.ncw > 0 { for pd.ncw > 0 {
fd.ncw-- pd.ncw--
fd.cw <- err pd.cw <- err
} }
} }
} }
...@@ -164,7 +180,7 @@ func (s *pollServer) CheckDeadlines() { ...@@ -164,7 +180,7 @@ func (s *pollServer) CheckDeadlines() {
// probably with a heap indexed by wakeup time. // probably with a heap indexed by wakeup time.
var nextDeadline int64 var nextDeadline int64
for key, fd := range s.pending { for key, pd := range s.pending {
var t int64 var t int64
var mode int var mode int
if key&1 == 0 { if key&1 == 0 {
...@@ -173,15 +189,15 @@ func (s *pollServer) CheckDeadlines() { ...@@ -173,15 +189,15 @@ func (s *pollServer) CheckDeadlines() {
mode = 'w' mode = 'w'
} }
if mode == 'r' { if mode == 'r' {
t = fd.rdeadline.value() t = pd.rdeadline.value()
} else { } else {
t = fd.wdeadline.value() t = pd.wdeadline.value()
} }
if t > 0 { if t > 0 {
if t <= now { if t <= now {
delete(s.pending, key) delete(s.pending, key)
s.poll.DelFD(fd.sysfd, mode) s.poll.DelFD(pd.sysfd, mode)
s.WakeFD(fd, mode, errTimeout) s.WakeFD(pd, mode, errTimeout)
} else if nextDeadline == 0 || t < nextDeadline { } else if nextDeadline == 0 || t < nextDeadline {
nextDeadline = t nextDeadline = t
} }
...@@ -220,48 +236,67 @@ func (s *pollServer) Run() { ...@@ -220,48 +236,67 @@ func (s *pollServer) Run() {
s.pr.Read(scratch[0:]) s.pr.Read(scratch[0:])
s.CheckDeadlines() s.CheckDeadlines()
} else { } else {
netfd := s.LookupFD(fd, mode) pd := s.LookupFD(fd, mode)
if netfd == nil { if pd == nil {
// This can happen because the WaitFD runs without // This can happen because the WaitFD runs without
// holding s's lock, so there might be a pending wakeup // holding s's lock, so there might be a pending wakeup
// for an fd that has been evicted. No harm done. // for an fd that has been evicted. No harm done.
continue continue
} }
s.WakeFD(netfd, mode, nil) s.WakeFD(pd, mode, nil)
} }
} }
} }
func (s *pollServer) PrepareRead(fd *netFD) error { func (pd *pollDesc) Close() {
if fd.rdeadline.expired() { }
func (pd *pollDesc) Lock() {
pd.pollServer.Lock()
}
func (pd *pollDesc) Unlock() {
pd.pollServer.Unlock()
}
func (pd *pollDesc) Wakeup() {
pd.pollServer.Wakeup()
}
func (pd *pollDesc) PrepareRead() error {
if pd.rdeadline.expired() {
return errTimeout return errTimeout
} }
return nil return nil
} }
func (s *pollServer) PrepareWrite(fd *netFD) error { func (pd *pollDesc) PrepareWrite() error {
if fd.wdeadline.expired() { if pd.wdeadline.expired() {
return errTimeout return errTimeout
} }
return nil return nil
} }
func (s *pollServer) WaitRead(fd *netFD) error { func (pd *pollDesc) WaitRead() error {
err := s.AddFD(fd, 'r') err := pd.pollServer.AddFD(pd, 'r')
if err == nil { if err == nil {
err = <-fd.cr err = <-pd.cr
} }
return err return err
} }
func (s *pollServer) WaitWrite(fd *netFD) error { func (pd *pollDesc) WaitWrite() error {
err := s.AddFD(fd, 'w') err := pd.pollServer.AddFD(pd, 'w')
if err == nil { if err == nil {
err = <-fd.cw err = <-pd.cw
} }
return err return err
} }
func (pd *pollDesc) Evict() bool {
return pd.pollServer.Evict(pd)
}
// Spread network FDs over several pollServers. // Spread network FDs over several pollServers.
var pollMaxN int var pollMaxN int
...@@ -292,31 +327,29 @@ func startServer(k int) { ...@@ -292,31 +327,29 @@ func startServer(k int) {
pollservers[k] = p pollservers[k] = p
} }
func pollServerInit(fd *netFD) error { func (pd *pollDesc) Init(fd *netFD) error {
pollN := runtime.GOMAXPROCS(0) pollN := runtime.GOMAXPROCS(0)
if pollN > pollMaxN { if pollN > pollMaxN {
pollN = pollMaxN pollN = pollMaxN
} }
k := fd.sysfd % pollN k := fd.sysfd % pollN
startServersOnce[k]() startServersOnce[k]()
fd.pollServer = pollservers[k] pd.sysfd = fd.sysfd
fd.cr = make(chan error, 1) pd.pollServer = pollservers[k]
fd.cw = make(chan error, 1) pd.cr = make(chan error, 1)
pd.cw = make(chan error, 1)
return nil return nil
} }
func (s *pollServer) Close(fd *netFD) {
}
// TODO(dfc) these unused error returns could be removed // TODO(dfc) these unused error returns could be removed
func setReadDeadline(fd *netFD, t time.Time) error { func setReadDeadline(fd *netFD, t time.Time) error {
fd.rdeadline.setTime(t) fd.pd.rdeadline.setTime(t)
return nil return nil
} }
func setWriteDeadline(fd *netFD, t time.Time) error { func setWriteDeadline(fd *netFD, t time.Time) error {
fd.wdeadline.setTime(t) fd.pd.wdeadline.setTime(t)
return nil return nil
} }
......
...@@ -20,7 +20,7 @@ type netFD struct { ...@@ -20,7 +20,7 @@ type netFD struct {
sysmu sync.Mutex sysmu sync.Mutex
sysref int sysref int
// must lock both sysmu and pollserver to write // must lock both sysmu and pollDesc to write
// can lock either to read // can lock either to read
closing bool closing bool
...@@ -30,8 +30,6 @@ type netFD struct { ...@@ -30,8 +30,6 @@ type netFD struct {
sotype int sotype int
isConnected bool isConnected bool
sysfile *os.File sysfile *os.File
cr chan error
cw chan error
net string net string
laddr Addr laddr Addr
raddr Addr raddr Addr
...@@ -39,14 +37,8 @@ type netFD struct { ...@@ -39,14 +37,8 @@ type netFD struct {
// serialize access to Read and Write methods // serialize access to Read and Write methods
rio, wio sync.Mutex rio, wio sync.Mutex
// read and write deadlines
rdeadline, wdeadline deadline
// owned by fd wait server
ncr, ncw int
// wait server // wait server
pollServer *pollServer pd pollDesc
} }
func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) { func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
...@@ -65,7 +57,7 @@ func newFD(fd, family, sotype int, net string) (*netFD, error) { ...@@ -65,7 +57,7 @@ func newFD(fd, family, sotype int, net string) (*netFD, error) {
sotype: sotype, sotype: sotype,
net: net, net: net,
} }
if err := pollServerInit(netfd); err != nil { if err := netfd.pd.Init(netfd); err != nil {
return nil, err return nil, err
} }
return netfd, nil return netfd, nil
...@@ -91,12 +83,12 @@ func (fd *netFD) name() string { ...@@ -91,12 +83,12 @@ func (fd *netFD) name() string {
func (fd *netFD) connect(ra syscall.Sockaddr) error { func (fd *netFD) connect(ra syscall.Sockaddr) error {
fd.wio.Lock() fd.wio.Lock()
defer fd.wio.Unlock() defer fd.wio.Unlock()
if err := fd.pollServer.PrepareWrite(fd); err != nil { if err := fd.pd.PrepareWrite(); err != nil {
return err return err
} }
err := syscall.Connect(fd.sysfd, ra) err := syscall.Connect(fd.sysfd, ra)
if err == syscall.EINPROGRESS { if err == syscall.EINPROGRESS {
if err = fd.pollServer.WaitWrite(fd); err != nil { if err = fd.pd.WaitWrite(); err != nil {
return err return err
} }
var e int var e int
...@@ -112,7 +104,7 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error { ...@@ -112,7 +104,7 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error {
} }
// Add a reference to this fd. // Add a reference to this fd.
// If closing==true, pollserver must be locked; mark the fd as closing. // If closing==true, pollDesc must be locked; mark the fd as closing.
// Returns an error if the fd cannot be used. // Returns an error if the fd cannot be used.
func (fd *netFD) incref(closing bool) error { func (fd *netFD) incref(closing bool) error {
fd.sysmu.Lock() fd.sysmu.Lock()
...@@ -135,7 +127,7 @@ func (fd *netFD) decref() { ...@@ -135,7 +127,7 @@ func (fd *netFD) decref() {
fd.sysref-- fd.sysref--
if fd.closing && fd.sysref == 0 && fd.sysfile != nil { if fd.closing && fd.sysref == 0 && fd.sysfile != nil {
fd.sysfile.Close() fd.sysfile.Close()
fd.pollServer.Close(fd) fd.pd.Close()
fd.sysfile = nil fd.sysfile = nil
fd.sysfd = -1 fd.sysfd = -1
} }
...@@ -143,21 +135,21 @@ func (fd *netFD) decref() { ...@@ -143,21 +135,21 @@ func (fd *netFD) decref() {
} }
func (fd *netFD) Close() error { func (fd *netFD) Close() error {
fd.pollServer.Lock() // needed for both fd.incref(true) and pollserver.Evict fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
if err := fd.incref(true); err != nil { if err := fd.incref(true); err != nil {
fd.pollServer.Unlock() fd.pd.Unlock()
return err return err
} }
// Unblock any I/O. Once it all unblocks and returns, // Unblock any I/O. Once it all unblocks and returns,
// so that it cannot be referring to fd.sysfd anymore, // so that it cannot be referring to fd.sysfd anymore,
// the final decref will close fd.sysfd. This should happen // the final decref will close fd.sysfd. This should happen
// fairly quickly, since all the I/O is non-blocking, and any // fairly quickly, since all the I/O is non-blocking, and any
// attempts to block in the pollserver will return errClosing. // attempts to block in the pollDesc will return errClosing.
doWakeup := fd.pollServer.Evict(fd) doWakeup := fd.pd.Evict()
fd.pollServer.Unlock() fd.pd.Unlock()
fd.decref() fd.decref()
if doWakeup { if doWakeup {
fd.pollServer.Wakeup() fd.pd.Wakeup()
} }
return nil return nil
} }
...@@ -189,7 +181,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) { ...@@ -189,7 +181,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
return 0, err return 0, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareRead(fd); err != nil { if err := fd.pd.PrepareRead(); err != nil {
return 0, &OpError{"read", fd.net, fd.raddr, err} return 0, &OpError{"read", fd.net, fd.raddr, err}
} }
for { for {
...@@ -197,7 +189,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) { ...@@ -197,7 +189,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
if err != nil { if err != nil {
n = 0 n = 0
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitRead(fd); err == nil { if err = fd.pd.WaitRead(); err == nil {
continue continue
} }
} }
...@@ -218,7 +210,7 @@ func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { ...@@ -218,7 +210,7 @@ func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
return 0, nil, err return 0, nil, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareRead(fd); err != nil { if err := fd.pd.PrepareRead(); err != nil {
return 0, nil, &OpError{"read", fd.net, fd.laddr, err} return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
} }
for { for {
...@@ -226,7 +218,7 @@ func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { ...@@ -226,7 +218,7 @@ func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
if err != nil { if err != nil {
n = 0 n = 0
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitRead(fd); err == nil { if err = fd.pd.WaitRead(); err == nil {
continue continue
} }
} }
...@@ -247,7 +239,7 @@ func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ...@@ -247,7 +239,7 @@ func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
return 0, 0, 0, nil, err return 0, 0, 0, nil, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareRead(fd); err != nil { if err := fd.pd.PrepareRead(); err != nil {
return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err} return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
} }
for { for {
...@@ -255,7 +247,7 @@ func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ...@@ -255,7 +247,7 @@ func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
if err != nil { if err != nil {
// TODO(dfc) should n and oobn be set to 0 // TODO(dfc) should n and oobn be set to 0
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitRead(fd); err == nil { if err = fd.pd.WaitRead(); err == nil {
continue continue
} }
} }
...@@ -283,7 +275,7 @@ func (fd *netFD) Write(p []byte) (nn int, err error) { ...@@ -283,7 +275,7 @@ func (fd *netFD) Write(p []byte) (nn int, err error) {
return 0, err return 0, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareWrite(fd); err != nil { if err := fd.pd.PrepareWrite(); err != nil {
return 0, &OpError{"write", fd.net, fd.raddr, err} return 0, &OpError{"write", fd.net, fd.raddr, err}
} }
for { for {
...@@ -296,7 +288,7 @@ func (fd *netFD) Write(p []byte) (nn int, err error) { ...@@ -296,7 +288,7 @@ func (fd *netFD) Write(p []byte) (nn int, err error) {
break break
} }
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitWrite(fd); err == nil { if err = fd.pd.WaitWrite(); err == nil {
continue continue
} }
} }
...@@ -322,13 +314,13 @@ func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) { ...@@ -322,13 +314,13 @@ func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
return 0, err return 0, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareWrite(fd); err != nil { if err := fd.pd.PrepareWrite(); err != nil {
return 0, &OpError{"write", fd.net, fd.raddr, err} return 0, &OpError{"write", fd.net, fd.raddr, err}
} }
for { for {
err = syscall.Sendto(fd.sysfd, p, 0, sa) err = syscall.Sendto(fd.sysfd, p, 0, sa)
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitWrite(fd); err == nil { if err = fd.pd.WaitWrite(); err == nil {
continue continue
} }
} }
...@@ -349,13 +341,13 @@ func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob ...@@ -349,13 +341,13 @@ func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob
return 0, 0, err return 0, 0, err
} }
defer fd.decref() defer fd.decref()
if err := fd.pollServer.PrepareWrite(fd); err != nil { if err := fd.pd.PrepareWrite(); err != nil {
return 0, 0, &OpError{"write", fd.net, fd.raddr, err} return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
} }
for { for {
err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0) err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitWrite(fd); err == nil { if err = fd.pd.WaitWrite(); err == nil {
continue continue
} }
} }
...@@ -380,14 +372,14 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e ...@@ -380,14 +372,14 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
var s int var s int
var rsa syscall.Sockaddr var rsa syscall.Sockaddr
if err = fd.pollServer.PrepareRead(fd); err != nil { if err = fd.pd.PrepareRead(); err != nil {
return nil, &OpError{"accept", fd.net, fd.laddr, err} return nil, &OpError{"accept", fd.net, fd.laddr, err}
} }
for { for {
s, rsa, err = accept(fd.sysfd) s, rsa, err = accept(fd.sysfd)
if err != nil { if err != nil {
if err == syscall.EAGAIN { if err == syscall.EAGAIN {
if err = fd.pollServer.WaitRead(fd); err == nil { if err = fd.pd.WaitRead(); err == nil {
continue continue
} }
} else if err == syscall.ECONNABORTED { } else if err == syscall.ECONNABORTED {
......
...@@ -83,7 +83,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { ...@@ -83,7 +83,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
break break
} }
if err1 == syscall.EAGAIN { if err1 == syscall.EAGAIN {
if err1 = c.pollServer.WaitWrite(c); err1 == nil { if err1 = c.pd.WaitWrite(); err1 == nil {
continue continue
} }
} }
......
...@@ -59,7 +59,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { ...@@ -59,7 +59,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
break break
} }
if err1 == syscall.EAGAIN { if err1 == syscall.EAGAIN {
if err1 = c.pollServer.WaitWrite(c); err1 == nil { if err1 = c.pd.WaitWrite(); err1 == nil {
continue continue
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment