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
 | |
| }
 |