core (Windows): Retry every 100ms for 2s if listener fails to bind

In testing, I've found that Windows doesn't release the socket right away even though the listener is closed, so calling caddy.Start() right after caddy.Stop() can fail. This change has server.ListenAndServe() try up to 20 times every 100ms to bind the listener, and only return an error if it doesn't succeed after 2 seconds. This might be kind of nifty for Unix, too, but there hasn't been a need for it yet.
This commit is contained in:
Matthew Holt 2015-10-31 13:22:23 -06:00
parent e4028b23c7
commit 4d71620cb0

View File

@ -117,8 +117,21 @@ func (s *Server) ListenAndServe() error {
ln, err := net.Listen("tcp", s.Addr)
if err != nil {
close(s.startChan)
return err
var succeeded bool
if runtime.GOOS == "windows" { // TODO: Limit this to Windows only? (it keeps sockets open after closing listeners)
for i := 0; i < 20; i++ {
time.Sleep(100 * time.Millisecond)
ln, err = net.Listen("tcp", s.Addr)
if err == nil {
succeeded = true
break
}
}
}
if !succeeded {
close(s.startChan)
return err
}
}
return s.serve(ln.(*net.TCPListener))