LEFT | RIGHT |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package sync | 5 package sync |
6 | 6 |
7 // A Pool is a set of temporary objects that may be individually saved | 7 // A Pool is a set of temporary objects that may be individually saved |
8 // and retrieved. | 8 // and retrieved. |
9 // | 9 // |
10 // Any item stored in the Pool may be removed automatically by the | 10 // Any item stored in the Pool may be removed automatically by the |
11 // implementation at any time without notification. | 11 // implementation at any time without notification. |
12 // If the Pool holds the only reference when this happens, the item | 12 // If the Pool holds the only reference when this happens, the item |
13 // might be deallocated. | 13 // might be deallocated. |
14 // | 14 // |
15 // A Pool is safe for use by multiple goroutines simultaneously. | 15 // A Pool is safe for use by multiple goroutines simultaneously. |
| 16 // |
| 17 // This is an experimental package and might not be released. |
16 type Pool struct { | 18 type Pool struct { |
17 next *Pool // for use by runtime. must be first. | 19 next *Pool // for use by runtime. must be first. |
18 list []interface{} // offset known to runtime | 20 list []interface{} // offset known to runtime |
19 mu Mutex // guards list | 21 mu Mutex // guards list |
20 | 22 |
21 // New optionally specifies a function to generate | 23 // New optionally specifies a function to generate |
22 // a value when Get would otherwise return nil. | 24 // a value when Get would otherwise return nil. |
23 // It may not be changed concurrently with calls to Get. | 25 // It may not be changed concurrently with calls to Get. |
24 New func() interface{} | 26 New func() interface{} |
25 } | 27 } |
26 | 28 |
27 func runtime_registerPool(*Pool) | 29 func runtime_registerPool(*Pool) |
28 | 30 |
29 // Put adds x to the pool. | 31 // Put adds x to the pool. |
30 func (p *Pool) Put(x interface{}) { | 32 func (p *Pool) Put(x interface{}) { |
31 if x == nil { | 33 if x == nil { |
32 return | 34 return |
33 } | 35 } |
34 p.mu.Lock() | 36 p.mu.Lock() |
35 if p.list == nil { | 37 if p.list == nil { |
36 runtime_registerPool(p) | 38 runtime_registerPool(p) |
37 } | 39 } |
38 p.list = append(p.list, x) | 40 p.list = append(p.list, x) |
39 p.mu.Unlock() | 41 p.mu.Unlock() |
40 } | 42 } |
41 | 43 |
42 // Get selects an arbitrary item from the Pool, removes it from the | 44 // Get selects an arbitrary item from the Pool, removes it from the |
43 // Pool, and returns it to the caller. | 45 // Pool, and returns it to the caller. |
44 // If the pool is empty and p.New is not set, Get returns nil. | 46 // Get may choose to ignore the pool and treat it as empty. |
| 47 // Callers should not assume any relation between values passed to Put and |
| 48 // the values returned by Get. |
| 49 // |
| 50 // If Get would otherwise return nil and p.New is non-nil, Get returns |
| 51 // the result of calling p.New. |
45 func (p *Pool) Get() interface{} { | 52 func (p *Pool) Get() interface{} { |
46 p.mu.Lock() | 53 p.mu.Lock() |
47 var x interface{} | 54 var x interface{} |
48 if n := len(p.list); n > 0 { | 55 if n := len(p.list); n > 0 { |
49 x = p.list[n-1] | 56 x = p.list[n-1] |
50 p.list[n-1] = nil // Just to be safe | 57 p.list[n-1] = nil // Just to be safe |
51 p.list = p.list[:n-1] | 58 p.list = p.list[:n-1] |
52 } | 59 } |
53 p.mu.Unlock() | 60 p.mu.Unlock() |
54 if x == nil && p.New != nil { | 61 if x == nil && p.New != nil { |
55 x = p.New() | 62 x = p.New() |
56 } | 63 } |
57 return x | 64 return x |
58 } | 65 } |
LEFT | RIGHT |