package grace import ( "net" "os" "syscall" "time" ) type graceListener struct { net.Listener stop chan error stopped bool server *Server } func newGraceListener(l net.Listener, srv *Server) (el *graceListener) { el = &graceListener{ Listener: l, stop: make(chan error), server: srv, } go func() { <-el.stop el.stopped = true el.stop <- el.Listener.Close() }() return } func (gl *graceListener) Accept() (c net.Conn, err error) { tc, err := gl.Listener.(*net.TCPListener).AcceptTCP() if err != nil { return } tc.SetKeepAlive(true) tc.SetKeepAlivePeriod(3 * time.Minute) c = graceConn{ Conn: tc, server: gl.server, } gl.server.wg.Add(1) return } func (gl *graceListener) Close() error { if gl.stopped { return syscall.EINVAL } gl.stop <- nil return <-gl.stop } func (gl *graceListener) File() *os.File { // returns a dup(2) - FD_CLOEXEC flag *not* set tl := gl.Listener.(*net.TCPListener) fl, _ := tl.File() return fl }