gtsocial-umbx

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

interface.go (1478B)


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