libgo: Merge from revision 18783:00cce3a34d7e of master library.
[official-gcc.git] / libgo / go / sync / pool.go
blob9eb07c3a03f26aebee9b403d0c92d7ccd44dd815
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package sync
7 // A Pool is a set of temporary objects that may be individually saved
8 // and retrieved.
9 //
10 // Any item stored in the Pool may be removed automatically by the
11 // implementation at any time without notification.
12 // If the Pool holds the only reference when this happens, the item
13 // might be deallocated.
15 // A Pool is safe for use by multiple goroutines simultaneously.
17 // Pool's intended use is for free lists maintained in global variables,
18 // typically accessed by multiple goroutines simultaneously. Using a
19 // Pool instead of a custom free list allows the runtime to reclaim
20 // entries from the pool when it makes sense to do so. An
21 // appropriate use of sync.Pool is to create a pool of temporary buffers
22 // shared between independent clients of a global resource. On the
23 // other hand, if a free list is maintained as part of an object used
24 // only by a single client and freed when the client completes,
25 // implementing that free list as a Pool is not appropriate.
27 // This is an experimental type and might not be released.
28 type Pool struct {
29 next *Pool // for use by runtime. must be first.
30 list []interface{} // offset known to runtime
31 mu Mutex // guards list
33 // New optionally specifies a function to generate
34 // a value when Get would otherwise return nil.
35 // It may not be changed concurrently with calls to Get.
36 New func() interface{}
39 func runtime_registerPool(*Pool)
41 // Put adds x to the pool.
42 func (p *Pool) Put(x interface{}) {
43 if x == nil {
44 return
46 p.mu.Lock()
47 if p.list == nil {
48 runtime_registerPool(p)
50 p.list = append(p.list, x)
51 p.mu.Unlock()
54 // Get selects an arbitrary item from the Pool, removes it from the
55 // Pool, and returns it to the caller.
56 // Get may choose to ignore the pool and treat it as empty.
57 // Callers should not assume any relation between values passed to Put and
58 // the values returned by Get.
60 // If Get would otherwise return nil and p.New is non-nil, Get returns
61 // the result of calling p.New.
62 func (p *Pool) Get() interface{} {
63 p.mu.Lock()
64 var x interface{}
65 if n := len(p.list); n > 0 {
66 x = p.list[n-1]
67 p.list[n-1] = nil // Just to be safe
68 p.list = p.list[:n-1]
70 p.mu.Unlock()
71 if x == nil && p.New != nil {
72 x = p.New()
74 return x