...

Source file src/github.com/docker/go-connections/sockets/inmem_socket.go

Documentation: github.com/docker/go-connections/sockets

     1  package sockets
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"sync"
     7  )
     8  
     9  var errClosed = errors.New("use of closed network connection")
    10  
    11  // InmemSocket implements net.Listener using in-memory only connections.
    12  type InmemSocket struct {
    13  	chConn  chan net.Conn
    14  	chClose chan struct{}
    15  	addr    string
    16  	mu      sync.Mutex
    17  }
    18  
    19  // dummyAddr is used to satisfy net.Addr for the in-mem socket
    20  // it is just stored as a string and returns the string for all calls
    21  type dummyAddr string
    22  
    23  // NewInmemSocket creates an in-memory only net.Listener
    24  // The addr argument can be any string, but is used to satisfy the `Addr()` part
    25  // of the net.Listener interface
    26  func NewInmemSocket(addr string, bufSize int) *InmemSocket {
    27  	return &InmemSocket{
    28  		chConn:  make(chan net.Conn, bufSize),
    29  		chClose: make(chan struct{}),
    30  		addr:    addr,
    31  	}
    32  }
    33  
    34  // Addr returns the socket's addr string to satisfy net.Listener
    35  func (s *InmemSocket) Addr() net.Addr {
    36  	return dummyAddr(s.addr)
    37  }
    38  
    39  // Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.
    40  func (s *InmemSocket) Accept() (net.Conn, error) {
    41  	select {
    42  	case conn := <-s.chConn:
    43  		return conn, nil
    44  	case <-s.chClose:
    45  		return nil, errClosed
    46  	}
    47  }
    48  
    49  // Close closes the listener. It will be unavailable for use once closed.
    50  func (s *InmemSocket) Close() error {
    51  	s.mu.Lock()
    52  	defer s.mu.Unlock()
    53  	select {
    54  	case <-s.chClose:
    55  	default:
    56  		close(s.chClose)
    57  	}
    58  	return nil
    59  }
    60  
    61  // Dial is used to establish a connection with the in-mem server
    62  func (s *InmemSocket) Dial(network, addr string) (net.Conn, error) {
    63  	srvConn, clientConn := net.Pipe()
    64  	select {
    65  	case s.chConn <- srvConn:
    66  	case <-s.chClose:
    67  		return nil, errClosed
    68  	}
    69  
    70  	return clientConn, nil
    71  }
    72  
    73  // Network returns the addr string, satisfies net.Addr
    74  func (a dummyAddr) Network() string {
    75  	return string(a)
    76  }
    77  
    78  // String returns the string form
    79  func (a dummyAddr) String() string {
    80  	return string(a)
    81  }
    82  

View as plain text