An interesting issue has arisen today where I have code that contains more than one Mutex, each covering locking for distinct Maps.
Here is a similar in struct of my source code that I am using:
type MyStruct struct {
dogMutex sync.RWMutex
dogMap map[int]Dog // keyed by PID
catMutex sync.RWMutex
catMap map[int]Cat // keyed by (localAddress + localPort)
}
A more detailed example of the issue is here: https://play.golang.org/p/eic8q2VrNq
After building the executable with 'go build -race ..." the generated executable reports the following race
As the code is way more complex than the example above, it is interesting to notice that the data race is reported on the areas indicated in the code.
The following stack is from the real application.
1) The write operation reported on wwww.go:95 is equivalent to my WRITE comment in the code (MethodOne)
2) The previous read operattion reported on wwww.go:218 is equivalent to my READ comment in the code (MethodTwo)
=================
WARNING: DATA RACE
Write at 0x00c420017890 by goroutine 97:
runtime.mapassign1()
/usr/local/go/src/runtime/hashmap.go:442 +0x0
main.(*NetworkManager).MethodOne()
/opt/doppler/src/xxx/yyy/wwww.go:95 +0x745
Previous read at 0x00c420017890 by goroutine 70:
runtime.mapiterinit()
/usr/local/go/src/runtime/hashmap.go:620 +0x0
main.NetworkManager.MethodTwo()
/opt/xxx/src/xxx/yyy/wwww.go:218 +0x1e9
main.(*NetworkManager).SomethingELse()
/opt/xxx/src/xxx/yyy/wwww.go:174 +0x99d
main.(*NetworkManager).SomethingFurther()
/opt/xxx/src/xxx/yyy/wwww.go:102 +0x3c
I am wondering if this is a proper way of using mutexes. My code has much concurrency, but I am focusing this question on the fact that the race detector is reporting based on Apples vs Bananas (two completely distinct mutexes)