tendermint/peer/listener.go

77 lines
1.4 KiB
Go
Raw Normal View History

2014-06-18 20:48:32 -07:00
package peer
import (
2014-06-24 17:28:40 -07:00
"atomic"
2014-06-18 20:48:32 -07:00
"net"
)
/* Listener */
2014-06-24 17:28:40 -07:00
type Listener interface {
Connections() <-chan *Connection
LocalAddress() *NetAddress
Stop()
}
/* DefaultListener */
type DefaultListener struct {
2014-06-18 20:48:32 -07:00
listener net.Listener
2014-06-24 17:28:40 -07:00
connections chan *Connection
stopped uint32
2014-06-18 20:48:32 -07:00
}
2014-06-24 17:28:40 -07:00
const (
DEFAULT_BUFFERED_CONNECTIONS = 10
)
func NewListener(protocol string, laddr string) *Listener {
2014-06-18 20:48:32 -07:00
ln, err := net.Listen(protocol, laddr)
if err != nil { panic(err) }
s := &Listener{
2014-06-24 17:28:40 -07:00
listener: ln,
connections: make(chan *Connection, DEFAULT_BUFFERED_CONNECTIONS),
2014-06-18 20:48:32 -07:00
}
2014-06-24 17:28:40 -07:00
go l.listenHandler()
2014-06-18 20:48:32 -07:00
return s
}
2014-06-24 17:28:40 -07:00
func (l *Listener) listenHandler() {
2014-06-18 20:48:32 -07:00
for {
2014-06-24 17:28:40 -07:00
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(con)
l.connections <- c
}
// cleanup
close(l.connections)
for _ = range l.connections {
// drain
2014-06-18 20:48:32 -07:00
}
}
2014-06-24 17:28:40 -07:00
func (l *Listener) Connections() <-chan *Connection {
return l.connections
2014-06-18 20:48:32 -07:00
}
2014-06-24 17:28:40 -07:00
func (l *Listener) LocalAddress() *NetAddress {
return NewNetAddress(l.listener.Addr())
}
func (l *Listener) Stop() {
if atomic.CompareAndSwapUint32(&l.stopped, 0, 1) {
l.listener.Close()
}
2014-06-18 20:48:32 -07:00
}