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.

Reply via email to