listen.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package netutil provides network utility functions, complementing the more
  5. // common ones in the net package.
  6. package netutil
  7. import (
  8. "net"
  9. "sync"
  10. )
  11. // LimitListener returns a Listener that accepts at most n simultaneous
  12. // connections from the provided Listener.
  13. func LimitListener(l net.Listener, n int) net.Listener {
  14. ch := make(chan struct{}, n)
  15. for i := 0; i < n; i++ {
  16. ch <- struct{}{}
  17. }
  18. return &limitListener{l, ch}
  19. }
  20. type limitListener struct {
  21. net.Listener
  22. ch chan struct{}
  23. }
  24. func (l *limitListener) Accept() (net.Conn, error) {
  25. <-l.ch
  26. c, err := l.Listener.Accept()
  27. if err != nil {
  28. return nil, err
  29. }
  30. return &limitListenerConn{Conn: c, ch: l.ch}, nil
  31. }
  32. type limitListenerConn struct {
  33. net.Conn
  34. ch chan<- struct{}
  35. close sync.Once
  36. }
  37. func (l *limitListenerConn) Close() error {
  38. err := l.Conn.Close()
  39. l.close.Do(func() {
  40. l.ch <- struct{}{}
  41. })
  42. return err
  43. }