Aias00 opened a new pull request, #3523:
URL: https://github.com/apache/dubbo-go/pull/3523
## What
`newP2CLoadBalance` and `newAdaptiveServiceCluster` read the package-level
`instance` **outside** `sync.Once.Do` (an `if instance == nil` fast path +
`return instance`), racing first-time concurrent initialization.
## Why
```go
var (
once sync.Once
instance loadbalance.LoadBalance
)
func newP2CLoadBalance(r randomPicker) loadbalance.LoadBalance {
if r == nil { r = defaultRnd }
if instance == nil { // unsynchronized read
once.Do(func() { instance = &p2cLoadBalance{...} })
}
return instance // unsynchronized read when check was
false
}
```
`sync.Once.Do` only establishes happens-before for callers that **call
`Do`**. A goroutine that observes `instance != nil` (check false) skips `Do`
and reads `instance` with no happens-before to the goroutine that wrote it
inside `Do`. Two concurrent first-time callers race on `instance`. The
identical pattern is in
`cluster/cluster/adaptivesvc/cluster.go:newAdaptiveServiceCluster`. Both
factories are registered in `init()`, so concurrent RPCs at process start hit
this path. `go test -race` flags it.
## Fix
Drop the `if instance == nil` fast path; always `once.Do(...)` then `return
instance`. `sync.Once.Do` guarantees all callers see the writes done inside
`Do`, and there is no read of `instance` outside `Do`. The p2c `r == nil`
defaulting moves inside the `once.Do` closure (only the first call's `r` is
used, identical to before).
## Tests
Added `TestNewP2CLoadBalanceConcurrent`: 100 goroutines racing the factory,
passing under `-race`. `p2c` package passes under `-race`.
Fixes #3522
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]