| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- package sftp
- // bufPool provides a pool of byte-slices to be reused in various parts of the package.
- // It is safe to use concurrently through a pointer.
- type bufPool struct {
- ch chan []byte
- blen int
- }
- func newBufPool(depth, bufLen int) *bufPool {
- return &bufPool{
- ch: make(chan []byte, depth),
- blen: bufLen,
- }
- }
- func (p *bufPool) Get() []byte {
- if p.blen <= 0 {
- panic("bufPool: new buffer creation length must be greater than zero")
- }
- for {
- select {
- case b := <-p.ch:
- if cap(b) < p.blen {
- // just in case: throw away any buffer with insufficient capacity.
- continue
- }
- return b[:p.blen]
- default:
- return make([]byte, p.blen)
- }
- }
- }
- func (p *bufPool) Put(b []byte) {
- if p == nil {
- // functional default: no reuse.
- return
- }
- if cap(b) < p.blen || cap(b) > p.blen*2 {
- // DO NOT reuse buffers with insufficient capacity.
- // This could cause panics when resizing to p.blen.
- // DO NOT reuse buffers with excessive capacity.
- // This could cause memory leaks.
- return
- }
- select {
- case p.ch <- b:
- default:
- }
- }
- type resChanPool chan chan result
- func newResChanPool(depth int) resChanPool {
- return make(chan chan result, depth)
- }
- func (p resChanPool) Get() chan result {
- select {
- case ch := <-p:
- return ch
- default:
- return make(chan result, 1)
- }
- }
- func (p resChanPool) Put(ch chan result) {
- select {
- case p <- ch:
- default:
- }
- }
|