Aias00 opened a new issue, #3518:
URL: https://github.com/apache/dubbo-go/issues/3518

   ### Problem
   
   `ServiceMappingChangedListenerImpl.OnEvent` reads the `stop` field under 
`lstn.mux` (the listener's own mutex), but `Stop` writes `stop` **without** 
that mutex:
   
   ```go
   // registry/servicediscovery/service_mapping_change_listener_impl.go
   func (lstn *ServiceMappingChangedListenerImpl) OnEvent(e observer.Event) 
error {
       lstn.mux.Lock()
       defer lstn.mux.Unlock()
       if lstn.stop == ServiceMappingListenerStop {   // read under mux
           return nil
       }
       ...
   }
   
   func (lstn *ServiceMappingChangedListenerImpl) Stop() {
       lstn.stop = ServiceMappingListenerStop            // write WITHOUT mux
   }
   ```
   
   `Stop` is called from `serviceDiscoveryRegistry.stopListen` under `s.lock` 
(the registry lock), not `lstn.mux`. So `OnEvent` (reading `stop` under `mux`) 
races `Stop` (writing `stop` without `mux`) — a data race on the `int` field, 
and a window where a stopped listener still processes a mapping event (spurious 
`SubscribeURL`/listener creation after teardown). `go test -race` flags it.
   
   ### Current behavior
   
   - `Stop()` writes `lstn.stop` with no synchronization.
   - `OnEvent()` reads `lstn.stop` under `lstn.mux`.
   - Concurrent `UnSubscribe` (→ `stopListen` → `Stop`) and a 
`ServiceMappingChangedEvent` delivered to `OnEvent` race on `stop`.
   
   ### Expected behavior
   
   `stop` should be read and written under the same mutex so that once `Stop` 
returns, no in-flight `OnEvent` proceeds past the stop check, and the field 
access is race-free.
   
   ### Suggested approach
   
   - Have `Stop` acquire `lstn.mux` before writing `stop` (the same mutex 
`OnEvent` reads `stop` under).
   - Verify `Stop` is never called re-entrantly from within `OnEvent`'s 
held-`mux` call stack (it is not — `Stop` is reached via 
`UnSubscribe`/`stopListen`, independent of the `OnEvent` → `SubscribeURL` 
path), so there is no self-deadlock.
   
   ### Acceptance criteria
   
   - [ ] `Stop` writes `stop` under `lstn.mux`.
   - [ ] A concurrency test (concurrent `Stop` vs `OnEvent`) passes under 
`-race`.
   - [ ] After `Stop` returns, `OnEvent` returns early without processing the 
event.
   


-- 
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]

Reply via email to