gtsocial-umbx

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

state.go (1478B)


      1 package atomics
      2 
      3 import "sync"
      4 
      5 // State provides user-friendly means of performing atomic-like
      6 // operations on a uint32 state, and allowing callbacks on successful
      7 // state change. This is a bit of a misnomer being where it is, as it
      8 // actually uses a mutex under-the-hood.
      9 type State struct {
     10 	mutex sync.Mutex
     11 	state uint32
     12 }
     13 
     14 // Store will update State value safely within mutex lock.
     15 func (st *State) Store(val uint32) {
     16 	st.mutex.Lock()
     17 	st.state = val
     18 	st.mutex.Unlock()
     19 }
     20 
     21 // Load will get value of State safely within mutex lock.
     22 func (st *State) Load() uint32 {
     23 	st.mutex.Lock()
     24 	state := st.state
     25 	st.mutex.Unlock()
     26 	return state
     27 }
     28 
     29 // WithLock performs fn within State mutex lock, useful if you want
     30 // to just use State's mutex for locking instead of creating another.
     31 func (st *State) WithLock(fn func()) {
     32 	st.mutex.Lock()
     33 	defer st.mutex.Unlock()
     34 	fn()
     35 }
     36 
     37 // Update performs fn within State mutex lock, with the current state
     38 // value provided as an argument, and return value used to update state.
     39 func (st *State) Update(fn func(state uint32) uint32) {
     40 	st.mutex.Lock()
     41 	defer st.mutex.Unlock()
     42 	st.state = fn(st.state)
     43 }
     44 
     45 // CAS performs a compare-and-swap on State, calling fn on success. Success value is also returned.
     46 func (st *State) CAS(cmp, swp uint32, fn func()) (ok bool) {
     47 	// Acquire lock
     48 	st.mutex.Lock()
     49 	defer st.mutex.Unlock()
     50 
     51 	// Perform CAS operation, fn() on success
     52 	if ok = (st.state == cmp); ok {
     53 		st.state = swp
     54 		fn()
     55 	}
     56 
     57 	return
     58 }