package peer import ( "sync/atomic" "net" ) /* Listener */ type Listener interface { Connections() <-chan *Connection LocalAddress() *NetAddress Stop() } /* DefaultListener */ type DefaultListener struct { listener net.Listener connections chan *Connection stopped uint32 } const ( DEFAULT_BUFFERED_CONNECTIONS = 10 ) func NewListener(protocol string, laddr string) Listener { ln, err := net.Listen(protocol, laddr) if err != nil { panic(err) } dl := &DefaultListener{ listener: ln, connections: make(chan *Connection, DEFAULT_BUFFERED_CONNECTIONS), } go dl.listenHandler() return dl } func (l *DefaultListener) listenHandler() { for { conn, err := l.listener.Accept() if atomic.LoadUint32(&l.stopped) == 1 { return } // listener wasn't stopped, // yet we encountered an error. if err != nil { panic(err) } c := NewConnection(conn) l.connections <- c } // cleanup close(l.connections) for _ = range l.connections { // drain } } func (l *DefaultListener) Connections() <-chan *Connection { return l.connections } func (l *DefaultListener) LocalAddress() *NetAddress { return NewNetAddress(l.listener.Addr()) } func (l *DefaultListener) Stop() { if atomic.CompareAndSwapUint32(&l.stopped, 0, 1) { l.listener.Close() } }