From 084e35c49dab4f1a5c7320991d8b24adb758ea07 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 5 Apr 2025 13:35:04 +0100 Subject: [PATCH] lib/http: fix race between Serve() and Shutdown() This was discovered by the race detector. --- lib/http/server.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/http/server.go b/lib/http/server.go index 98f4f5ca7..f098d7593 100644 --- a/lib/http/server.go +++ b/lib/http/server.go @@ -229,7 +229,8 @@ type Server struct { cfg Config template *TemplateConfig htmlTemplate *template.Template - usingAuth bool // set if we are using auth middleware + usingAuth bool // set if we are using auth middleware + mu sync.Mutex // mutex protects RW variables below atexitHandle atexit.FnHandle } @@ -524,7 +525,9 @@ func (s *Server) Serve() { go ii.serve(&s.wg) } // Install an atexit handler to shutdown gracefully + s.mu.Lock() s.atexitHandle = atexit.Register(func() { _ = s.Shutdown() }) + s.mu.Unlock() } // Wait blocks while the server is serving requests @@ -543,10 +546,12 @@ const gracefulShutdownTime = 10 * time.Second // Shutdown gracefully shuts down the server func (s *Server) Shutdown() error { // Stop the atexit handler + s.mu.Lock() if s.atexitHandle != nil { atexit.Unregister(s.atexitHandle) s.atexitHandle = nil } + s.mu.Unlock() for _, ii := range s.instances { expiry := time.Now().Add(gracefulShutdownTime) ctx, cancel := context.WithDeadline(context.Background(), expiry)