Fix "PR c++/92804 ICE trying to use concept as a nested-name-specifier"
[official-gcc.git] / libgo / go / net / net_fake.go
blob0c48dd5c03bb47ead18b5571a1c635865ca83dd4
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Fake networking for js/wasm. It is intended to allow tests of other package to pass.
7 // +build js,wasm
9 package net
11 import (
12 "context"
13 "internal/poll"
14 "io"
15 "os"
16 "sync"
17 "syscall"
18 "time"
21 var listenersMu sync.Mutex
22 var listeners = make(map[string]*netFD)
24 var portCounterMu sync.Mutex
25 var portCounter = 0
27 func nextPort() int {
28 portCounterMu.Lock()
29 defer portCounterMu.Unlock()
30 portCounter++
31 return portCounter
34 // Network file descriptor.
35 type netFD struct {
36 r *bufferedPipe
37 w *bufferedPipe
38 incoming chan *netFD
40 closedMu sync.Mutex
41 closed bool
43 // immutable until Close
44 listener bool
45 family int
46 sotype int
47 net string
48 laddr Addr
49 raddr Addr
51 // unused
52 pfd poll.FD
53 isConnected bool // handshake completed or use of association with peer
56 // socket returns a network file descriptor that is ready for
57 // asynchronous I/O using the network poller.
58 func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) (*netFD, error) {
59 fd := &netFD{family: family, sotype: sotype, net: net}
61 if laddr != nil && raddr == nil { // listener
62 l := laddr.(*TCPAddr)
63 fd.laddr = &TCPAddr{
64 IP: l.IP,
65 Port: nextPort(),
66 Zone: l.Zone,
68 fd.listener = true
69 fd.incoming = make(chan *netFD, 1024)
70 listenersMu.Lock()
71 listeners[fd.laddr.(*TCPAddr).String()] = fd
72 listenersMu.Unlock()
73 return fd, nil
76 fd.laddr = &TCPAddr{
77 IP: IPv4(127, 0, 0, 1),
78 Port: nextPort(),
80 fd.raddr = raddr
81 fd.r = newBufferedPipe(65536)
82 fd.w = newBufferedPipe(65536)
84 fd2 := &netFD{family: fd.family, sotype: sotype, net: net}
85 fd2.laddr = fd.raddr
86 fd2.raddr = fd.laddr
87 fd2.r = fd.w
88 fd2.w = fd.r
89 listenersMu.Lock()
90 l, ok := listeners[fd.raddr.(*TCPAddr).String()]
91 if !ok {
92 listenersMu.Unlock()
93 return nil, syscall.ECONNREFUSED
95 l.incoming <- fd2
96 listenersMu.Unlock()
98 return fd, nil
101 func (fd *netFD) Read(p []byte) (n int, err error) {
102 return fd.r.Read(p)
105 func (fd *netFD) Write(p []byte) (nn int, err error) {
106 return fd.w.Write(p)
109 func (fd *netFD) Close() error {
110 fd.closedMu.Lock()
111 if fd.closed {
112 fd.closedMu.Unlock()
113 return nil
115 fd.closed = true
116 fd.closedMu.Unlock()
118 if fd.listener {
119 listenersMu.Lock()
120 delete(listeners, fd.laddr.String())
121 close(fd.incoming)
122 fd.listener = false
123 listenersMu.Unlock()
124 return nil
127 fd.r.Close()
128 fd.w.Close()
129 return nil
132 func (fd *netFD) closeRead() error {
133 fd.r.Close()
134 return nil
137 func (fd *netFD) closeWrite() error {
138 fd.w.Close()
139 return nil
142 func (fd *netFD) accept() (*netFD, error) {
143 c, ok := <-fd.incoming
144 if !ok {
145 return nil, syscall.EINVAL
147 return c, nil
150 func (fd *netFD) SetDeadline(t time.Time) error {
151 fd.r.SetReadDeadline(t)
152 fd.w.SetWriteDeadline(t)
153 return nil
156 func (fd *netFD) SetReadDeadline(t time.Time) error {
157 fd.r.SetReadDeadline(t)
158 return nil
161 func (fd *netFD) SetWriteDeadline(t time.Time) error {
162 fd.w.SetWriteDeadline(t)
163 return nil
166 func newBufferedPipe(softLimit int) *bufferedPipe {
167 p := &bufferedPipe{softLimit: softLimit}
168 p.rCond.L = &p.mu
169 p.wCond.L = &p.mu
170 return p
173 type bufferedPipe struct {
174 softLimit int
175 mu sync.Mutex
176 buf []byte
177 closed bool
178 rCond sync.Cond
179 wCond sync.Cond
180 rDeadline time.Time
181 wDeadline time.Time
184 func (p *bufferedPipe) Read(b []byte) (int, error) {
185 p.mu.Lock()
186 defer p.mu.Unlock()
188 for {
189 if p.closed && len(p.buf) == 0 {
190 return 0, io.EOF
192 if !p.rDeadline.IsZero() {
193 d := time.Until(p.rDeadline)
194 if d <= 0 {
195 return 0, syscall.EAGAIN
197 time.AfterFunc(d, p.rCond.Broadcast)
199 if len(p.buf) > 0 {
200 break
202 p.rCond.Wait()
205 n := copy(b, p.buf)
206 p.buf = p.buf[n:]
207 p.wCond.Broadcast()
208 return n, nil
211 func (p *bufferedPipe) Write(b []byte) (int, error) {
212 p.mu.Lock()
213 defer p.mu.Unlock()
215 for {
216 if p.closed {
217 return 0, syscall.ENOTCONN
219 if !p.wDeadline.IsZero() {
220 d := time.Until(p.wDeadline)
221 if d <= 0 {
222 return 0, syscall.EAGAIN
224 time.AfterFunc(d, p.wCond.Broadcast)
226 if len(p.buf) <= p.softLimit {
227 break
229 p.wCond.Wait()
232 p.buf = append(p.buf, b...)
233 p.rCond.Broadcast()
234 return len(b), nil
237 func (p *bufferedPipe) Close() {
238 p.mu.Lock()
239 defer p.mu.Unlock()
241 p.closed = true
242 p.rCond.Broadcast()
243 p.wCond.Broadcast()
246 func (p *bufferedPipe) SetReadDeadline(t time.Time) {
247 p.mu.Lock()
248 defer p.mu.Unlock()
250 p.rDeadline = t
251 p.rCond.Broadcast()
254 func (p *bufferedPipe) SetWriteDeadline(t time.Time) {
255 p.mu.Lock()
256 defer p.mu.Unlock()
258 p.wDeadline = t
259 p.wCond.Broadcast()
262 func sysSocket(family, sotype, proto int) (int, error) {
263 return 0, syscall.ENOSYS
266 func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
267 return 0, nil, syscall.ENOSYS
270 func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
271 return 0, 0, 0, nil, syscall.ENOSYS
274 func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
275 return 0, syscall.ENOSYS
278 func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
279 return 0, 0, syscall.ENOSYS
282 func (fd *netFD) dup() (f *os.File, err error) {
283 return nil, syscall.ENOSYS