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.

Reply via email to