Switching to pointer receivers everywhere actually makes this worse. Any access is potentially a data race. 

It stills seems like this is a compiler issue. There needs to be a way to synchronize the pointer to value copy in conjunction with other synchronization. 

The only way to do this would be to write your own pointer to value conversion methods that have synchronization. 

On Nov 14, 2023, at 8:36 PM, Mike Schinkel <m...@newclarity.net> wrote:


On Tuesday, November 14, 2023 at 6:16:58 PM UTC-5 burak serdar wrote:
It is a data race because calling rpc.version() makes a copy of rpc,
which causes reading the field rpc.result concurrently while it is
being written by the goroutine.
 
Thank you for explaining. I think I am starting to see it.

On Tuesday, November 14, 2023 at 7:08:57 PM UTC-5 burak serdar wrote:
I do not agree that this is because how the compiler works. A value
receiver is equivalent to pass-by-value argument, that is:

rcp.version()

is equivalent to:

RPC.version(rpc)

thus, creating the copy of the rpc variable. So, the compiler may
choose to avoid the race by not copying it, or by inlining the version
function, but according to the spec, it is passed by value, i.e., it
is copied.

I agree with your assertion — if you fix it to work correctly by using RPC.version(*rpc)— but that is actually a different concern than I and I think Robert Engels were discussing.  

Your example above calls a method directly on the struct, we were discussing calling via an interface. 

Given that Go already performs some "magic" when it calls an interface — i.e. when the interface value contains a pointer and the method receive is a value — I think he was exploring whether it would be viable to avoid creating a copy when the method does not read or update any property.

Still, that doesn't seem to be all that useful because most of the time a value method would want to read a property so it is probably not worth the effort.

--------

But back to the original concern. It seems that race conditions do not arise when using mixed receivers while only executing the main goroutine, right?

And if using only pointer receivers then we can still have a data race if those methods are being called in multiple goroutines where methods both read and update the same properties, right?.  

Given that, the race conditions and the mixed pointers seem orthogonal concerns?   But I do now recognize that if you are using the same objects across goroutines and you have an updating pointer method then calling any value method would create a race condition so mixing receivers is more likely to cause a race condition when sharing objects across goroutines.

Still, it seems to me then that the guidance should be to not to access any object concurrently in more than one goroutine instead of to avoid mixed receivers, since that laters only addresses part of the race condition problem?  (BTW, by "not-concurrently" I mean that you could first access in goroutine 1 then pass it via a channel to goroutine 2 where you could access it, but once goroutine 1 submits the object to the channel it should no longer attempt to access it.)

Or again, am I missing something obvious?   

-Mike


--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/8f46fecc-1d5f-4507-8209-76adef294bafn%40googlegroups.com.

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/F4895A80-66A0-4957-B369-0CDFD6DB16EA%40ix.netcom.com.

Reply via email to