string.go (1375B)
1 package atomics 2 3 import ( 4 "sync/atomic" 5 "unsafe" 6 ) 7 8 // String provides user-friendly means of performing atomic operations on string types. 9 type String struct{ ptr unsafe.Pointer } 10 11 // NewString will return a new String instance initialized with zero value. 12 func NewString() *String { 13 var v string 14 return &String{ 15 ptr: unsafe.Pointer(&v), 16 } 17 } 18 19 // Store will atomically store string value in address contained within v. 20 func (v *String) Store(val string) { 21 atomic.StorePointer(&v.ptr, unsafe.Pointer(&val)) 22 } 23 24 // Load will atomically load string value at address contained within v. 25 func (v *String) Load() string { 26 return *(*string)(atomic.LoadPointer(&v.ptr)) 27 } 28 29 // CAS performs a compare-and-swap for a(n) string value at address contained within v. 30 func (v *String) CAS(cmp, swp string) bool { 31 for { 32 // Load current value at address 33 ptr := atomic.LoadPointer(&v.ptr) 34 cur := *(*string)(ptr) 35 36 // Perform comparison against current 37 if !(cur == cmp) { 38 return false 39 } 40 41 // Attempt to replace pointer 42 if atomic.CompareAndSwapPointer( 43 &v.ptr, 44 ptr, 45 unsafe.Pointer(&swp), 46 ) { 47 return true 48 } 49 } 50 } 51 52 // Swap atomically stores new string value into address contained within v, and returns previous value. 53 func (v *String) Swap(swp string) string { 54 ptr := unsafe.Pointer(&swp) 55 ptr = atomic.SwapPointer(&v.ptr, ptr) 56 return *(*string)(ptr) 57 }