rpcsrv: refactor subscribe routine

Move shutdown check after subsCounterLock is taken in the end of
`(s *Server) subscribe` in order to avoid extra locks holding.
This commit is contained in:
Anna Shaleva 2022-11-18 10:40:28 +03:00
parent b7f19a54d5
commit 4df9a5e379

View file

@ -2447,12 +2447,6 @@ func (s *Server) subscribe(reqParams params.Params, sub *subscriber) (interface{
} }
s.subsLock.Lock() s.subsLock.Lock()
select {
case <-s.shutdown:
s.subsLock.Unlock()
return nil, neorpc.NewInternalServerError("server is shutting down")
default:
}
var id int var id int
for ; id < len(sub.feeds); id++ { for ; id < len(sub.feeds); id++ {
if sub.feeds[id].event == neorpc.InvalidEventID { if sub.feeds[id].event == neorpc.InvalidEventID {
@ -2468,6 +2462,12 @@ func (s *Server) subscribe(reqParams params.Params, sub *subscriber) (interface{
s.subsLock.Unlock() s.subsLock.Unlock()
s.subsCounterLock.Lock() s.subsCounterLock.Lock()
select {
case <-s.shutdown:
s.subsCounterLock.Unlock()
return nil, neorpc.NewInternalServerError("server is shutting down")
default:
}
s.subscribeToChannel(event) s.subscribeToChannel(event)
s.subsCounterLock.Unlock() s.subsCounterLock.Unlock()
return strconv.FormatInt(int64(id), 10), nil return strconv.FormatInt(int64(id), 10), nil
@ -2646,10 +2646,9 @@ chloop:
} }
s.subsLock.RUnlock() s.subsLock.RUnlock()
} }
// It's important to do it with lock held because no subscription routine // It's important to do it with subsCounterLock held because no subscription routine
// should be running concurrently to this one. And even if one is to run // should be running concurrently to this one. And even if one is to run
// after unlock, it'll see closed s.shutdown and won't subscribe. // after unlock, it'll see closed s.shutdown and won't subscribe.
s.subsLock.Lock()
s.subsCounterLock.Lock() s.subsCounterLock.Lock()
// There might be no subscription in reality, but it's not a problem as // There might be no subscription in reality, but it's not a problem as
// core.Blockchain allows unsubscribing non-subscribed channels. // core.Blockchain allows unsubscribing non-subscribed channels.
@ -2661,7 +2660,6 @@ chloop:
s.coreServer.UnsubscribeFromNotaryRequests(s.notaryRequestCh) s.coreServer.UnsubscribeFromNotaryRequests(s.notaryRequestCh)
} }
s.subsCounterLock.Unlock() s.subsCounterLock.Unlock()
s.subsLock.Unlock()
drainloop: drainloop:
for { for {
select { select {