package stoppableListener import ( "errors" "net" "time" ) type StoppableListener struct { *net.TCPListener //Wrapped listener stop chan int //Channel used only to indicate listener should shutdown } func New(l net.Listener) (*StoppableListener, error) { tcpL, ok := l.(*net.TCPListener) if !ok { return nil, errors.New("Cannot wrap listener") } retval := &StoppableListener{} retval.TCPListener = tcpL retval.stop = make(chan int) return retval, nil } var StoppedError = errors.New("Listener stopped") func (sl *StoppableListener) Accept() (net.Conn, error) { for { //Wait up to one second for a new connection sl.SetDeadline(time.Now().Add(time.Second)) newConn, err := sl.TCPListener.Accept() //Check for the channel being closed select { case <-sl.stop: return nil, StoppedError default: //If the channel is still open, continue as normal } if err != nil { netErr, ok := err.(net.Error) //If this is a timeout, then continue to wait for //new connections if ok && netErr.Timeout() && netErr.Temporary() { continue } } return newConn, err } } func (sl *StoppableListener) Stop() { close(sl.stop) }