gtsocial-umbx

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

error.go (1350B)


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