github.com/pkg/sftp@v1.13.6/pool.go (about) 1 package sftp 2 3 // bufPool provides a pool of byte-slices to be reused in various parts of the package. 4 // It is safe to use concurrently through a pointer. 5 type bufPool struct { 6 ch chan []byte 7 blen int 8 } 9 10 func newBufPool(depth, bufLen int) *bufPool { 11 return &bufPool{ 12 ch: make(chan []byte, depth), 13 blen: bufLen, 14 } 15 } 16 17 func (p *bufPool) Get() []byte { 18 if p.blen <= 0 { 19 panic("bufPool: new buffer creation length must be greater than zero") 20 } 21 22 for { 23 select { 24 case b := <-p.ch: 25 if cap(b) < p.blen { 26 // just in case: throw away any buffer with insufficient capacity. 27 continue 28 } 29 30 return b[:p.blen] 31 32 default: 33 return make([]byte, p.blen) 34 } 35 } 36 } 37 38 func (p *bufPool) Put(b []byte) { 39 if p == nil { 40 // functional default: no reuse. 41 return 42 } 43 44 if cap(b) < p.blen || cap(b) > p.blen*2 { 45 // DO NOT reuse buffers with insufficient capacity. 46 // This could cause panics when resizing to p.blen. 47 48 // DO NOT reuse buffers with excessive capacity. 49 // This could cause memory leaks. 50 return 51 } 52 53 select { 54 case p.ch <- b: 55 default: 56 } 57 } 58 59 type resChanPool chan chan result 60 61 func newResChanPool(depth int) resChanPool { 62 return make(chan chan result, depth) 63 } 64 65 func (p resChanPool) Get() chan result { 66 select { 67 case ch := <-p: 68 return ch 69 default: 70 return make(chan result, 1) 71 } 72 } 73 74 func (p resChanPool) Put(ch chan result) { 75 select { 76 case p <- ch: 77 default: 78 } 79 }