diff --git a/src/archive/zip/register.go b/src/archive/zip/register.go index 8fccbf7ca09..2e76386b1fd 100644 --- a/src/archive/zip/register.go +++ b/src/archive/zip/register.go @@ -64,6 +64,44 @@ func (w *pooledFlateWriter) Close() error { return err } +var flateReaderPool sync.Pool + +func newFlateReader(r io.Reader) io.ReadCloser { + fr, ok := flateReaderPool.Get().(io.ReadCloser) + if ok { + fr.(flate.Resetter).Reset(r, nil) + } else { + fr = flate.NewReader(r) + } + return &pooledFlateReader{fr: fr} +} + +type pooledFlateReader struct { + mu sync.Mutex // guards Close and Read + fr io.ReadCloser +} + +func (r *pooledFlateReader) Read(p []byte) (n int, err error) { + r.mu.Lock() + defer r.mu.Unlock() + if r.fr == nil { + return 0, errors.New("Read after Close") + } + return r.fr.Read(p) +} + +func (r *pooledFlateReader) Close() error { + r.mu.Lock() + defer r.mu.Unlock() + var err error + if r.fr != nil { + err = r.fr.Close() + flateReaderPool.Put(r.fr) + r.fr = nil + } + return err +} + var ( mu sync.RWMutex // guards compressor and decompressor maps @@ -74,7 +112,7 @@ var ( decompressors = map[uint16]Decompressor{ Store: ioutil.NopCloser, - Deflate: flate.NewReader, + Deflate: newFlateReader, } )