| // Copyright 2013 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package sync | |
| // A Pool is a set of temporary objects that may be individually saved | |
| // and retrieved. | |
| // | |
| // Any item stored in the Pool may be removed automatically by the | |
| // implementation at any time without notification. | |
| // If the Pool holds the only reference when this happens, the item | |
| // might be deallocated. | |
| // | |
| // A Pool is safe for use by multiple goroutines simultaneously. | |
| // | |
| // Pool's intended use is for free lists maintained in global variables, | |
| // typically accessed by multiple goroutines simultaneously. Using a | |
| // Pool instead of a custom free list allows the runtime to reclaim | |
| // entries from the pool when it makes sense to do so. An | |
| // appropriate use of sync.Pool is to create a pool of temporary buffers | |
| // shared between independent clients of a global resource. On the | |
| // other hand, if a free list is maintained as part of an object used | |
| // only by a single client and freed when the client completes, | |
| // implementing that free list as a Pool is not appropriate. | |
| // | |
| // This is an experimental type and might not be released. | |
| type Pool struct { | |
| next *Pool // for use by runtime. must be first. | |
| list []interface{} // offset known to runtime | |
| mu Mutex // guards list | |
| // New optionally specifies a function to generate | |
| // a value when Get would otherwise return nil. | |
| // It may not be changed concurrently with calls to Get. | |
| New func() interface{} | |
| } | |
| func runtime_registerPool(*Pool) | |
| // Put adds x to the pool. | |
| func (p *Pool) Put(x interface{}) { | |
| if x == nil { | |
| return | |
| } | |
| p.mu.Lock() | |
| if p.list == nil { | |
| runtime_registerPool(p) | |
| } | |
| p.list = append(p.list, x) | |
| p.mu.Unlock() | |
| } | |
| // Get selects an arbitrary item from the Pool, removes it from the | |
| // Pool, and returns it to the caller. | |
| // Get may choose to ignore the pool and treat it as empty. | |
| // Callers should not assume any relation between values passed to Put and | |
| // the values returned by Get. | |
| // | |
| // If Get would otherwise return nil and p.New is non-nil, Get returns | |
| // the result of calling p.New. | |
| func (p *Pool) Get() interface{} { | |
| p.mu.Lock() | |
| var x interface{} | |
| if n := len(p.list); n > 0 { | |
| x = p.list[n-1] | |
| p.list[n-1] = nil // Just to be safe | |
| p.list = p.list[:n-1] | |
| } | |
| p.mu.Unlock() | |
| if x == nil && p.New != nil { | |
| x = p.New() | |
| } | |
| return x | |
| } |