bytes.go (1380B)
1 package atomics 2 3 import ( 4 "sync/atomic" 5 "unsafe" 6 ) 7 8 // Bytes provides user-friendly means of performing atomic operations on []byte types. 9 type Bytes struct{ ptr unsafe.Pointer } 10 11 // NewBytes will return a new Bytes instance initialized with zero value. 12 func NewBytes() *Bytes { 13 var v []byte 14 return &Bytes{ 15 ptr: unsafe.Pointer(&v), 16 } 17 } 18 19 // Store will atomically store []byte value in address contained within v. 20 func (v *Bytes) Store(val []byte) { 21 atomic.StorePointer(&v.ptr, unsafe.Pointer(&val)) 22 } 23 24 // Load will atomically load []byte value at address contained within v. 25 func (v *Bytes) Load() []byte { 26 return *(*[]byte)(atomic.LoadPointer(&v.ptr)) 27 } 28 29 // CAS performs a compare-and-swap for a(n) []byte value at address contained within v. 30 func (v *Bytes) CAS(cmp, swp []byte) bool { 31 for { 32 // Load current value at address 33 ptr := atomic.LoadPointer(&v.ptr) 34 cur := *(*[]byte)(ptr) 35 36 // Perform comparison against current 37 if !(string(cur) == string(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 []byte value into address contained within v, and returns previous value. 53 func (v *Bytes) Swap(swp []byte) []byte { 54 ptr := unsafe.Pointer(&swp) 55 ptr = atomic.SwapPointer(&v.ptr, ptr) 56 return *(*[]byte)(ptr) 57 }