github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/pipelistener/listener.go (about)

     1  package pipelistener
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  )
     7  
     8  var _ net.Listener = (*Listener)(nil)
     9  
    10  type Listener struct {
    11  	pipe chan net.Conn
    12  	done chan struct{}
    13  }
    14  
    15  func New(channelSize int) *Listener {
    16  	return &Listener{
    17  		pipe: make(chan net.Conn, channelSize),
    18  		done: make(chan struct{}),
    19  	}
    20  }
    21  
    22  func (l *Listener) Serve(conn net.Conn) {
    23  	l.pipe <- conn
    24  }
    25  
    26  func (l *Listener) Accept() (net.Conn, error) {
    27  	select {
    28  	case conn := <-l.pipe:
    29  		return conn, nil
    30  	case <-l.done:
    31  		return nil, io.ErrClosedPipe
    32  	}
    33  }
    34  
    35  func (l *Listener) Close() error {
    36  	select {
    37  	case <-l.done:
    38  		return io.ErrClosedPipe
    39  	default:
    40  	}
    41  	close(l.done)
    42  	return nil
    43  }
    44  
    45  func (l *Listener) Addr() net.Addr {
    46  	return addr{}
    47  }
    48  
    49  type addr struct{}
    50  
    51  func (a addr) Network() string {
    52  	return "pipe"
    53  }
    54  
    55  func (a addr) String() string {
    56  	return "pipe"
    57  }