From 1d2a9f2ace4e3787a50736a9fb2a15a77df22c90 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 12 May 2016 10:04:05 -0400 Subject: [PATCH] Fix concurrent map access in bytespipe When getting and returning a buffer, need to make sure to syncronize access to the pools map. Signed-off-by: Brian Goff --- ioutils/bytespipe.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ioutils/bytespipe.go b/ioutils/bytespipe.go index 59bba96..eca129b 100644 --- a/ioutils/bytespipe.go +++ b/ioutils/bytespipe.go @@ -20,7 +20,8 @@ var ( // ErrClosed is returned when Write is called on a closed BytesPipe. ErrClosed = errors.New("write to closed BytesPipe") - bufPools = make(map[int]*sync.Pool) + bufPools = make(map[int]*sync.Pool) + bufPoolsLock sync.Mutex ) // BytesPipe is io.ReadWriteCloser which works similarly to pipe(queue). @@ -164,17 +165,21 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) { func returnBuffer(b *fixedBuffer) { b.Reset() + bufPoolsLock.Lock() pool := bufPools[b.Cap()] + bufPoolsLock.Unlock() if pool != nil { pool.Put(b) } } func getBuffer(size int) *fixedBuffer { + bufPoolsLock.Lock() pool, ok := bufPools[size] if !ok { pool = &sync.Pool{New: func() interface{} { return &fixedBuffer{buf: make([]byte, 0, size)} }} bufPools[size] = pool } + bufPoolsLock.Unlock() return pool.Get().(*fixedBuffer) }