...
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
12 type InmemSocket struct {
13 chConn chan net.Conn
14 chClose chan struct{}
15 addr string
16 mu sync.Mutex
17 }
18
19
20
21 type dummyAddr string
22
23
24
25
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
35 func (s *InmemSocket) Addr() net.Addr {
36 return dummyAddr(s.addr)
37 }
38
39
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
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
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
74 func (a dummyAddr) Network() string {
75 return string(a)
76 }
77
78
79 func (a dummyAddr) String() string {
80 return string(a)
81 }
82
View as plain text