63 lines
		
	
	
		
			991 B
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			991 B
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
}
 |