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.

Reply via email to