GoPLS Viewer

Home|gopls/internal/jsonrpc2_v2/net.go
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.
4
5package jsonrpc2
6
7import (
8    "context"
9    "io"
10    "net"
11    "os"
12)
13
14// This file contains implementations of the transport primitives that use the standard network
15// package.
16
17// NetListenOptions is the optional arguments to the NetListen function.
18type NetListenOptions struct {
19    NetListenConfig net.ListenConfig
20    NetDialer       net.Dialer
21}
22
23// NetListener returns a new Listener that listens on a socket using the net package.
24func NetListener(ctx context.Contextnetworkaddress stringoptions NetListenOptions) (Listenererror) {
25    lnerr := options.NetListenConfig.Listen(ctxnetworkaddress)
26    if err != nil {
27        return nilerr
28    }
29    return &netListener{netln}, nil
30}
31
32// netListener is the implementation of Listener for connections made using the net package.
33type netListener struct {
34    net net.Listener
35}
36
37// Accept blocks waiting for an incoming connection to the listener.
38func (l *netListenerAccept(context.Context) (io.ReadWriteClosererror) {
39    return l.net.Accept()
40}
41
42// Close will cause the listener to stop listening. It will not close any connections that have
43// already been accepted.
44func (l *netListenerClose() error {
45    addr := l.net.Addr()
46    err := l.net.Close()
47    if addr.Network() == "unix" {
48        rerr := os.Remove(addr.String())
49        if rerr != nil && err == nil {
50            err = rerr
51        }
52    }
53    return err
54}
55
56// Dialer returns a dialer that can be used to connect to the listener.
57func (l *netListenerDialer() Dialer {
58    return NetDialer(l.net.Addr().Network(), l.net.Addr().String(), net.Dialer{})
59}
60
61// NetDialer returns a Dialer using the supplied standard network dialer.
62func NetDialer(networkaddress stringnd net.DialerDialer {
63    return &netDialer{
64        networknetwork,
65        addressaddress,
66        dialer:  nd,
67    }
68}
69
70type netDialer struct {
71    network string
72    address string
73    dialer  net.Dialer
74}
75
76func (n *netDialerDial(ctx context.Context) (io.ReadWriteClosererror) {
77    return n.dialer.DialContext(ctxn.networkn.address)
78}
79
80// NetPipeListener returns a new Listener that listens using net.Pipe.
81// It is only possibly to connect to it using the Dialer returned by the
82// Dialer method, each call to that method will generate a new pipe the other
83// side of which will be returned from the Accept call.
84func NetPipeListener(ctx context.Context) (Listenererror) {
85    return &netPiper{
86        done:   make(chan struct{}),
87        dialedmake(chan io.ReadWriteCloser),
88    }, nil
89}
90
91// netPiper is the implementation of Listener build on top of net.Pipes.
92type netPiper struct {
93    done   chan struct{}
94    dialed chan io.ReadWriteCloser
95}
96
97// Accept blocks waiting for an incoming connection to the listener.
98func (l *netPiperAccept(context.Context) (io.ReadWriteClosererror) {
99    // Block until the pipe is dialed or the listener is closed,
100    // preferring the latter if already closed at the start of Accept.
101    select {
102    case <-l.done:
103        return nilerrClosed
104    default:
105    }
106    select {
107    case rwc := <-l.dialed:
108        return rwcnil
109    case <-l.done:
110        return nilerrClosed
111    }
112}
113
114// Close will cause the listener to stop listening. It will not close any connections that have
115// already been accepted.
116func (l *netPiperClose() error {
117    // unblock any accept calls that are pending
118    close(l.done)
119    return nil
120}
121
122func (l *netPiperDialer() Dialer {
123    return l
124}
125
126func (l *netPiperDial(ctx context.Context) (io.ReadWriteClosererror) {
127    clientserver := net.Pipe()
128
129    select {
130    case l.dialed <- server:
131        return clientnil
132
133    case <-l.done:
134        client.Close()
135        server.Close()
136        return nilerrClosed
137    }
138}
139
MembersX
netPiper.Accept.l
netPiper.Dialer.l
NetListenOptions.NetListenConfig
NetListener
netListener.net
netListener.Accept
netListener.Close
netDialer
netPiper.Dial
NetListenOptions.NetDialer
netListener.Close.l
NetDialer.address
NetDialer.nd
netPiper.dialed
netPiper.Accept
netListener.Close.addr
netDialer.Dial.n
NetPipeListener.ctx
netPiper.Dial.l
netDialer.dialer
netPiper.Dial.client
NetListener.ctx
NetListener.network
NetListener.address
NetListener.options
netListener
NetDialer.network
os
NetListenOptions
NetListener.ln
NetDialer
netDialer.Dial.ctx
netPiper.Dialer
netListener.Close.err
netListener.Close.BlockStmt.rerr
netListener.Dialer.l
netDialer.network
NetPipeListener
netPiper.Close
netPiper.Dial.ctx
netPiper.Dial.server
net
NetListener.err
netListener.Accept.l
netListener.Dialer
netDialer.Dial
netPiper.Close.l
netDialer.address
netPiper
netPiper.done
Members
X