forked from quic-go/quic-go
http3: use a slice instead of a map to store active listeners (#5087)
* http3: use a slice instead of a map to store active listeners This list will be relatively short, therefore it will be more performant to use a slice instead of a map. No functional change expected. * http3: rename listenerInfo to listener
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -101,8 +102,9 @@ var ServerContextKey = &contextKey{"http3-server"}
|
||||
// than its string representation.
|
||||
var RemoteAddrContextKey = &contextKey{"remote-addr"}
|
||||
|
||||
// listenerInfo contains info about specific listener added with addListener
|
||||
type listenerInfo struct {
|
||||
// listener contains info about specific listener added with addListener
|
||||
type listener struct {
|
||||
ln *QUICEarlyListener
|
||||
port int // 0 means that no info about port is available
|
||||
}
|
||||
|
||||
@@ -183,7 +185,7 @@ type Server struct {
|
||||
Logger *slog.Logger
|
||||
|
||||
mutex sync.RWMutex
|
||||
listeners map[*QUICEarlyListener]listenerInfo
|
||||
listeners []listener
|
||||
|
||||
closed bool
|
||||
closeCtx context.Context // canceled when the server is closed
|
||||
@@ -406,28 +408,22 @@ func (s *Server) generateAltSvcHeader() {
|
||||
s.altSvcHeader = strings.Join(altSvc, ",")
|
||||
}
|
||||
|
||||
// We store a pointer to interface in the map set. This is safe because we only
|
||||
// call trackListener via Serve and can track+defer untrack the same pointer to
|
||||
// local variable there. We never need to compare a Listener from another caller.
|
||||
func (s *Server) addListener(l *QUICEarlyListener) error {
|
||||
if s.closed {
|
||||
return http.ErrServerClosed
|
||||
}
|
||||
if s.listeners == nil {
|
||||
s.listeners = make(map[*QUICEarlyListener]listenerInfo)
|
||||
}
|
||||
s.init()
|
||||
|
||||
laddr := (*l).Addr()
|
||||
if port, err := extractPort(laddr.String()); err == nil {
|
||||
s.listeners[l] = listenerInfo{port}
|
||||
s.listeners = append(s.listeners, listener{ln: l, port: port})
|
||||
} else {
|
||||
logger := s.Logger
|
||||
if logger == nil {
|
||||
logger = slog.Default()
|
||||
}
|
||||
logger.Error("Unable to extract port from listener, will not be announced using SetQUICHeaders", "local addr", laddr, "error", err)
|
||||
s.listeners[l] = listenerInfo{}
|
||||
s.listeners = append(s.listeners, listener{ln: l, port: 0})
|
||||
}
|
||||
s.generateAltSvcHeader()
|
||||
return nil
|
||||
@@ -436,7 +432,10 @@ func (s *Server) addListener(l *QUICEarlyListener) error {
|
||||
func (s *Server) removeListener(l *QUICEarlyListener) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
delete(s.listeners, l)
|
||||
|
||||
s.listeners = slices.DeleteFunc(s.listeners, func(info listener) bool {
|
||||
return info.ln == l
|
||||
})
|
||||
s.generateAltSvcHeader()
|
||||
}
|
||||
|
||||
@@ -681,8 +680,8 @@ func (s *Server) Close() error {
|
||||
s.closeCancel()
|
||||
|
||||
var err error
|
||||
for ln := range s.listeners {
|
||||
if cerr := (*ln).Close(); cerr != nil && err == nil {
|
||||
for _, info := range s.listeners {
|
||||
if cerr := (*info.ln).Close(); cerr != nil && err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user