diff --git a/internal/nbconn/nbconn.go b/internal/nbconn/nbconn.go index eb751509..f4419f0f 100644 --- a/internal/nbconn/nbconn.go +++ b/internal/nbconn/nbconn.go @@ -73,10 +73,11 @@ type NetConn struct { readFlushLock sync.Mutex // non-blocking writes with syscall.RawConn are done with a callback function. By using these fields instead of the - // callback functions closure to pass the buf argument and receive the n and err results we avoid some allocations. - nonblockWriteBuf []byte - nonblockWriteErr error - nonblockWriteN int + // callback functions closure to pass the buf argument and receive the n and err results we avoid some allocations. + nonblockWriteFunc func(fd uintptr) (done bool) + nonblockWriteBuf []byte + nonblockWriteErr error + nonblockWriteN int readDeadlineLock sync.Mutex readDeadline time.Time diff --git a/internal/nbconn/nbconn_real_non_block.go b/internal/nbconn/nbconn_real_non_block.go index ee48d129..00c13adb 100644 --- a/internal/nbconn/nbconn_real_non_block.go +++ b/internal/nbconn/nbconn_real_non_block.go @@ -12,13 +12,17 @@ import ( // realNonblockingWrite does a non-blocking write. readFlushLock must already be held. func (c *NetConn) realNonblockingWrite(b []byte) (n int, err error) { + if c.nonblockWriteFunc == nil { + c.nonblockWriteFunc = func(fd uintptr) (done bool) { + c.nonblockWriteN, c.nonblockWriteErr = syscall.Write(int(fd), c.nonblockWriteBuf) + return true + } + } c.nonblockWriteBuf = b c.nonblockWriteN = 0 c.nonblockWriteErr = nil - err = c.rawConn.Write(func(fd uintptr) (done bool) { - c.nonblockWriteN, c.nonblockWriteErr = syscall.Write(int(fd), c.nonblockWriteBuf) - return true - }) + + err = c.rawConn.Write(c.nonblockWriteFunc) n = c.nonblockWriteN if err == nil && c.nonblockWriteErr != nil { if errors.Is(c.nonblockWriteErr, syscall.EWOULDBLOCK) {