Diff
1diff --git a/cmd/soft/serve/serve.go b/cmd/soft/serve/serve.go
2index 7472f3d0be14300f5dcb827197308abfcc6d9ff6..5f54676d9adcac3980a067ee85bf981dbfc1ce6b 100644
3--- a/cmd/soft/serve/serve.go
4+++ b/cmd/soft/serve/serve.go
5@@ -8,7 +8,6 @@ import (
6 "os/signal"
7 "path/filepath"
8 "strconv"
9- "sync"
10 "syscall"
11 "time"
12
13@@ -84,7 +83,7 @@ var (
14
15 lch := make(chan error, 1)
16 done := make(chan os.Signal, 1)
17- doneOnce := sync.OnceFunc(func() { close(done) })
18+ testStop := make(chan struct{})
19
20 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
21
22@@ -95,7 +94,7 @@ var (
23 h := s.HTTPServer.Server.Handler
24 s.HTTPServer.Server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
25 if r.URL.Path == "/__stop" && r.Method == http.MethodHead {
26- doneOnce()
27+ close(testStop)
28 return
29 }
30 h.ServeHTTP(w, r)
31@@ -104,7 +103,6 @@ var (
32
33 go func() {
34 lch <- s.Start()
35- doneOnce()
36 }()
37
38 for {
39@@ -113,6 +111,8 @@ var (
40 if err != nil {
41 return fmt.Errorf("server error: %w", err)
42 }
43+ // Server exited cleanly; shut down
44+ goto shutdown
45 case sig := <-done:
46 if sig == syscall.SIGHUP {
47 s.logger.Info("received SIGHUP signal, reloading TLS certificates if enabled")
48@@ -121,11 +121,15 @@ var (
49 }
50 continue
51 }
52+ // Real signal received; shut down
53+ goto shutdown
54+ case <-testStop:
55+ // Test hook triggered; shut down
56+ goto shutdown
57 }
58-
59- break
60 }
61
62+ shutdown:
63 ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
64 defer cancel()
65 if err := s.Shutdown(ctx); err != nil {