diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go index ef5c00aee0833cd913d1bdbd86e3ff0dbaf4794e..5589c9c68256b0a09cdaae143526c3d475d7b486 100644 --- a/src/os/dir_unix.go +++ b/src/os/dir_unix.go @@ -10,15 +10,16 @@ package os import ( "io" "runtime" + "sync" "syscall" "unsafe" ) // Auxiliary information if the File describes a directory type dirInfo struct { - buf []byte // buffer for directory I/O - nbuf int // length of buf; return value from Getdirentries - bufp int // location of next record in buf. + buf *[]byte // buffer for directory I/O + nbuf int // length of buf; return value from Getdirentries + bufp int // location of next record in buf. } const ( @@ -26,14 +27,26 @@ const ( blockSize = 8192 ) -func (d *dirInfo) close() {} +var dirBufPool = sync.Pool{ + New: func() interface{} { + // The buffer must be at least a block long. + buf := make([]byte, blockSize) + return &buf + }, +} + +func (d *dirInfo) close() { + if d.buf != nil { + dirBufPool.Put(d.buf) + d.buf = nil + } +} func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) { // If this file has no dirinfo, create one. if f.dirinfo == nil { f.dirinfo = new(dirInfo) - // The buffer must be at least a block long. - f.dirinfo.buf = make([]byte, blockSize) + f.dirinfo.buf = dirBufPool.Get().(*[]byte) } d := f.dirinfo @@ -55,7 +68,7 @@ func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEn if d.bufp >= d.nbuf { d.bufp = 0 var errno error - d.nbuf, errno = f.pfd.ReadDirent(d.buf) + d.nbuf, errno = f.pfd.ReadDirent(*d.buf) runtime.KeepAlive(f) if errno != nil { return names, dirents, infos, &PathError{Op: "readdirent", Path: f.name, Err: errno} @@ -66,7 +79,7 @@ func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEn } // Drain the buffer - buf := d.buf[d.bufp:d.nbuf] + buf := (*d.buf)[d.bufp:d.nbuf] reclen, ok := direntReclen(buf) if !ok || reclen > uint64(len(buf)) { break diff --git a/src/os/file_unix.go b/src/os/file_unix.go index e8b286c9ee8aff35ba95441c469d16603fa93918..b5d87fcb731c2777c433963d68f701847d90e154 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -247,6 +247,7 @@ func (file *file) close() error { } if file.dirinfo != nil { file.dirinfo.close() + file.dirinfo = nil } var err error if e := file.pfd.Close(); e != nil {