- Timestamp:
- Feb 9, 2021, 4:34:46 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cmd/soju/main.go
r418 r449 8 8 "net/http" 9 9 "net/url" 10 "os" 11 "os/signal" 10 12 "strings" 13 "syscall" 11 14 12 15 "github.com/pires/go-proxyproto" … … 90 93 ln = proxyProtoListener(ln, srv) 91 94 go func() { 92 log.Fatal(srv.Serve(ln)) 95 if err := srv.Serve(ln); err != nil { 96 log.Printf("serving %q: %v", listen, err) 97 } 93 98 }() 94 99 case "irc+insecure": … … 103 108 ln = proxyProtoListener(ln, srv) 104 109 go func() { 105 log.Fatal(srv.Serve(ln)) 110 if err := srv.Serve(ln); err != nil { 111 log.Printf("serving %q: %v", listen, err) 112 } 106 113 }() 107 114 case "wss": … … 116 123 } 117 124 go func() { 118 log.Fatal(httpSrv.ListenAndServeTLS("", "")) 125 if err := httpSrv.ListenAndServeTLS("", ""); err != nil { 126 log.Fatalf("serving %q: %v", listen, err) 127 } 119 128 }() 120 129 case "ws+insecure": … … 128 137 } 129 138 go func() { 130 log.Fatal(httpSrv.ListenAndServe()) 139 if err := httpSrv.ListenAndServe(); err != nil { 140 log.Fatalf("serving %q: %v", listen, err) 141 } 131 142 }() 132 143 case "ident": … … 145 156 ln = proxyProtoListener(ln, srv) 146 157 go func() { 147 log.Fatal(srv.Identd.Serve(ln)) 158 if err := srv.Identd.Serve(ln); err != nil { 159 log.Printf("serving %q: %v", listen, err) 160 } 148 161 }() 149 162 default: … … 153 166 log.Printf("server listening on %q", listen) 154 167 } 155 log.Fatal(srv.Run()) 168 169 sigCh := make(chan os.Signal, 1) 170 signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) 171 172 if err := srv.Start(); err != nil { 173 log.Fatal(err) 174 } 175 176 <-sigCh 177 log.Print("shutting down server") 178 srv.Shutdown() 156 179 } 157 180 -
trunk/server.go
r409 r449 6 6 "net" 7 7 "net/http" 8 "strings" 8 9 "sync" 9 10 "sync/atomic" … … 55 56 Identd *Identd // can be nil 56 57 57 db *DB 58 59 lock sync.Mutex 60 users map[string]*user 58 db *DB 59 stopWG sync.WaitGroup 60 61 lock sync.Mutex 62 listeners map[net.Listener]struct{} 63 users map[string]*user 61 64 } 62 65 … … 65 68 Logger: log.New(log.Writer(), "", log.LstdFlags), 66 69 HistoryLimit: 1000, 70 db: db, 71 listeners: make(map[net.Listener]struct{}), 67 72 users: make(map[string]*user), 68 db: db,69 73 } 70 74 } … … 74 78 } 75 79 76 func (s *Server) Run() error {80 func (s *Server) Start() error { 77 81 users, err := s.db.ListUsers() 78 82 if err != nil { … … 86 90 s.lock.Unlock() 87 91 88 select {} 92 return nil 93 } 94 95 func (s *Server) Shutdown() { 96 s.lock.Lock() 97 for ln := range s.listeners { 98 if err := ln.Close(); err != nil { 99 s.Logger.Printf("failed to stop listener: %v", err) 100 } 101 } 102 for _, u := range s.users { 103 u.events <- eventStop{} 104 } 105 s.lock.Unlock() 106 107 s.stopWG.Wait() 89 108 } 90 109 … … 117 136 s.users[u.Username] = u 118 137 138 s.stopWG.Add(1) 139 119 140 go func() { 120 141 u.run() … … 123 144 delete(s.users, u.Username) 124 145 s.lock.Unlock() 146 147 s.stopWG.Done() 125 148 }() 126 149 … … 146 169 147 170 func (s *Server) Serve(ln net.Listener) error { 171 s.lock.Lock() 172 s.listeners[ln] = struct{}{} 173 s.lock.Unlock() 174 175 s.stopWG.Add(1) 176 177 defer func() { 178 s.lock.Lock() 179 delete(s.listeners, ln) 180 s.lock.Unlock() 181 182 s.stopWG.Done() 183 }() 184 148 185 for { 149 186 conn, err := ln.Accept() 150 if err != nil { 187 // TODO: use net.ErrClosed when available 188 if err != nil && strings.Contains(err.Error(), "use of closed network connection") { 189 return nil 190 } else if err != nil { 151 191 return fmt.Errorf("failed to accept connection: %v", err) 152 192 }
Note:
See TracChangeset
for help on using the changeset viewer.