@@ -21,7 +21,7 @@ type Once struct {
21
21
// The hot path is inlined at every call site.
22
22
// Placing done first allows more compact instructions on some architectures (amd64/386),
23
23
// and fewer instructions (to calculate offset) on other architectures.
24
- done uint32
24
+ done atomic. Uint32
25
25
m Mutex
26
26
}
27
27
@@ -48,7 +48,7 @@ type Once struct {
48
48
func (o * Once ) Do (f func ()) {
49
49
// Note: Here is an incorrect implementation of Do:
50
50
//
51
- // if atomic.CompareAndSwapUint32(& o.done, 0, 1) {
51
+ // if o.done.CompareAndSwap( 0, 1) {
52
52
// f()
53
53
// }
54
54
//
@@ -58,9 +58,9 @@ func (o *Once) Do(f func()) {
58
58
// call f, and the second would return immediately, without
59
59
// waiting for the first's call to f to complete.
60
60
// This is why the slow path falls back to a mutex, and why
61
- // the atomic.StoreUint32 must be delayed until after f returns.
61
+ // the o.done.Store must be delayed until after f returns.
62
62
63
- if atomic . LoadUint32 ( & o .done ) == 0 {
63
+ if o .done . Load ( ) == 0 {
64
64
// Outlined slow-path to allow inlining of the fast-path.
65
65
o .doSlow (f )
66
66
}
@@ -69,8 +69,8 @@ func (o *Once) Do(f func()) {
69
69
func (o * Once ) doSlow (f func ()) {
70
70
o .m .Lock ()
71
71
defer o .m .Unlock ()
72
- if o .done == 0 {
73
- defer atomic . StoreUint32 ( & o .done , 1 )
72
+ if o .done . Load () == 0 {
73
+ defer o .done . Store ( 1 )
74
74
f ()
75
75
}
76
76
}
0 commit comments