diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/braintree/manners/listener.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/braintree/manners/listener.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/listener.go b/Godeps/_workspace/src/github.com/braintree/manners/listener.go new file mode 100644 index 000000000..dd84e4a2e --- /dev/null +++ b/Godeps/_workspace/src/github.com/braintree/manners/listener.go @@ -0,0 +1,49 @@ +package manners + +import ( + "net" + "sync" +) + +func NewListener(l net.Listener, s *GracefulServer) *GracefulListener { + return &GracefulListener{l, true, s, sync.RWMutex{}} +} + +// A GracefulListener differs from a standard net.Listener in one way: if +// Accept() is called after it is gracefully closed, it returns a +// listenerAlreadyClosed error. The GracefulServer will ignore this +// error. +type GracefulListener struct { + net.Listener + open bool + server *GracefulServer + rw sync.RWMutex +} + +func (l *GracefulListener) Accept() (net.Conn, error) { + conn, err := l.Listener.Accept() + if err != nil { + l.rw.RLock() + defer l.rw.RUnlock() + if !l.open { + err = listenerAlreadyClosed{err} + } + return nil, err + } + return conn, nil +} + +func (l *GracefulListener) Close() error { + l.rw.Lock() + defer l.rw.Unlock() + if !l.open { + return nil + } + l.open = false + err := l.Listener.Close() + return err +} + +type listenerAlreadyClosed struct { + error +} |