rwmtx.go (1931B)
1 package rwmtx 2 3 import ( 4 "sync" 5 ) 6 7 type Mtx[T any] struct { 8 sync.Mutex 9 v T 10 } 11 12 func NewMtx[T any](v T) Mtx[T] { 13 return Mtx[T]{v: v} 14 } 15 16 func (m *Mtx[T]) Val() *T { 17 return &m.v 18 } 19 20 func (m *Mtx[T]) Get() T { 21 m.Lock() 22 defer m.Unlock() 23 return m.v 24 } 25 26 func (m *Mtx[T]) Set(v T) { 27 m.Lock() 28 defer m.Unlock() 29 m.v = v 30 } 31 32 func (m *Mtx[T]) With(clb func(v *T)) { 33 _ = m.WithE(func(tx *T) error { 34 clb(tx) 35 return nil 36 }) 37 } 38 39 func (m *Mtx[T]) WithE(clb func(v *T) error) error { 40 m.Lock() 41 defer m.Unlock() 42 return clb(&m.v) 43 } 44 45 //---------------------- 46 47 type RWMtx[T any] struct { 48 sync.RWMutex 49 v T 50 } 51 52 func New[T any](v T) RWMtx[T] { 53 return RWMtx[T]{v: v} 54 } 55 56 func (m *RWMtx[T]) Val() *T { 57 return &m.v 58 } 59 60 func (m *RWMtx[T]) Get() T { 61 m.RLock() 62 defer m.RUnlock() 63 return m.v 64 } 65 66 func (m *RWMtx[T]) Set(v T) { 67 m.Lock() 68 defer m.Unlock() 69 m.v = v 70 } 71 72 func (m *RWMtx[T]) Replace(newVal T) (old T) { 73 m.With(func(v *T) { 74 old = *v 75 *v = newVal 76 }) 77 return 78 } 79 80 func (m *RWMtx[T]) RWith(clb func(v T)) { 81 _ = m.RWithE(func(tx T) error { 82 clb(tx) 83 return nil 84 }) 85 } 86 87 func (m *RWMtx[T]) RWithE(clb func(v T) error) error { 88 m.RLock() 89 defer m.RUnlock() 90 return clb(m.v) 91 } 92 93 func (m *RWMtx[T]) With(clb func(v *T)) { 94 _ = m.WithE(func(tx *T) error { 95 clb(tx) 96 return nil 97 }) 98 } 99 100 func (m *RWMtx[T]) WithE(clb func(v *T) error) error { 101 m.Lock() 102 defer m.Unlock() 103 return clb(&m.v) 104 } 105 106 //---------------------- 107 108 type RWMtxSlice[T any] struct { 109 RWMtx[[]T] 110 } 111 112 func (s *RWMtxSlice[T]) Each(clb func(T)) { 113 s.RWith(func(v []T) { 114 for _, e := range v { 115 clb(e) 116 } 117 }) 118 } 119 120 func (s *RWMtxSlice[T]) Append(els ...T) { 121 s.With(func(v *[]T) { *v = append(*v, els...) }) 122 } 123 124 func (s *RWMtxSlice[T]) Clone() (out []T) { 125 s.RWith(func(v []T) { 126 out = make([]T, len(v)) 127 copy(out, v) 128 }) 129 return 130 } 131 132 //---------------------- 133 134 type RWMtxUInt64[T ~uint64] struct { 135 RWMtx[T] 136 } 137 138 func (s *RWMtxUInt64[T]) Incr(diff T) { 139 s.With(func(v *T) { *v += diff }) 140 }