I don't know if it's documented or not. In the language reference you can see the rules for method calls:
https://golang.org/ref/spec#Calls https://golang.org/ref/spec#Method_sets A hint might have been that object should have mutated, but it didn't. It's in a class of errors that becomes recognizable once you've been bitten by it. In the example you gave, use of mutex seems redundant to me; execution of func passed into update is already guarded by atomic. On Sun, Apr 14, 2019 at 9:51 AM <michael.f.el...@gmail.com> wrote: > Thanks, Skip. That fixes it. Is the need for a pointer receiver documented > somewhere? It's not something that even crossed my mind given that the > neither the compiler nor golint complained. I suppose it makes sense if I > think of func (x) foo(y) {} as being an alternate way of writing func > foo(x, y) {}. In that case, it's clear that a copy of x is being passed > since that's Go's default. > > While this topic is still alive, I'd like to ask a follow-on question: Is > the use of sync/atomic actually needed in this example or is it sufficient > to wrap all accesses in mutex Lock/Unlock (using the same mutex, of course). > > > > On Sunday, April 14, 2019 at 12:08:55 PM UTC-4, Skip wrote: >> >> 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 <michae...@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 golan...@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. > -- 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.