aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/os/dir_unix.go29
-rw-r--r--src/os/file_unix.go1
2 files changed, 22 insertions, 8 deletions
diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go
index ef5c00aee0..5589c9c682 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 e8b286c9ee..b5d87fcb73 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 {