Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / go-connections / sockets / inmem_socket.go
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 }