gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }