The receiver for load and update should be the original object not a copy. https://play.golang.org/p/XCZC0OVhGMa
On Sun, Apr 14, 2019, 7:56 AM <michael.f.el...@gmail.com> wrote: > > https://play.golang.org/p/6aQYNjojyBD > > I'm clearly missing something about the way sync.Mutex and atomic.Value > work in Go. > > I'm attempting to write a pair of concurrency safe methods, load() and > update(), for accessing a struct. The struct is stored as an atomic.Value > and accessed with atomic.Load and atomic.Value. I'm also wrapping the > accesses within a mutex Lock/Unlock. That's probably unneeded for my > load() method but I added it trying to figure out why it's not returning > updated info. In my minimal example below (also in the Go Playground link > above) the output of main() should be: > > s={65535} > v={65535} > > but I get > > s={65535} > v={0} > > indicating that the updated value is not available after the call to > update(). > > The only thing I'm doing that's a little different from the examples in > the doc for sync/atomic is passing a function that takes a pointer to a > struct instance to my update function. I do that to make it easy to write > code that updates just a few items in the state struct (which in my real > application has many members instead of just one as shown here.) > > Apologies for wasting the group's time if I've overlooked a brain-dead > error, but I've been fooling with this for several hours now and can't see > why it shouldn't be working, > > > package main > > import ( > "fmt" > "sync" > "sync/atomic" > ) > > type state struct { > R4000 uint16 > } > type guardedState struct { > v atomic.Value > } > > var stateMutex = sync.Mutex{} > var gState guardedState > > func init() { > gState.v.Store(state{}) > } > > func (g guardedState) load() state { > stateMutex.Lock() > defer stateMutex.Unlock() > s := gState.v.Load() > return s.(state) > } > > func (g guardedState) update(f func(*state)) { > stateMutex.Lock() > defer stateMutex.Unlock() > s := g.v.Load().(state) > f(&s) > g.v.Store(s) > } > > func main() { > f := func(s *state) { > s.R4000 = 65535 > fmt.Printf("s=%v\n", *s) > } > gState.update(f) > v := gState.load() > fmt.Printf("v=%v\n", v) > } > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.