listener.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package enet
  2. import (
  3. "errors"
  4. "net"
  5. "sync/atomic"
  6. )
  7. var _ net.Listener = (*Listener)(nil)
  8. // Listener is an implementation of net.Listener
  9. type Listener struct {
  10. ch chan net.Conn
  11. closeCh chan struct{}
  12. closed int32
  13. nowNum int32
  14. addr net.Addr
  15. }
  16. // NewListener returns an initialized Listener
  17. func NewListener() *Listener {
  18. return &Listener{ch: make(chan net.Conn, 10), closeCh: make(chan struct{})}
  19. }
  20. // SendConn is used to add connection to the listener
  21. func (bl *Listener) SendConn(c net.Conn) error {
  22. if atomic.LoadInt32(&bl.closed) == 1 {
  23. return errors.New("the listener is already closed")
  24. }
  25. atomic.AddInt32(&bl.nowNum, 1)
  26. select {
  27. case bl.ch <- c:
  28. return nil
  29. case <-bl.closeCh:
  30. }
  31. if atomic.AddInt32(&bl.nowNum, -1) == 0 && atomic.LoadInt32(&bl.closed) == 1 {
  32. close(bl.ch)
  33. }
  34. return errors.New("the listener is already closed")
  35. }
  36. // Accept is used to get connection from the listener
  37. func (bl *Listener) Accept() (net.Conn, error) {
  38. c := <-bl.ch
  39. if c == nil {
  40. return nil, errors.New("the listener is already closed")
  41. }
  42. return c, nil
  43. }
  44. // Close is used to close the listener, it will discard all existing connections
  45. func (bl *Listener) Close() error {
  46. if atomic.CompareAndSwapInt32(&bl.closed, 0, 1) {
  47. close(bl.closeCh)
  48. }
  49. return nil
  50. }
  51. // Addr returns the listener's address'
  52. func (bl *Listener) Addr() net.Addr {
  53. return bl.addr
  54. }