internal/jsonrpc2_v2: initialize async before binding
The lsprpc package needs to wait on the newly bound connection to perform some tear-down, so it must be safe to call conn.Wait from Bind. Achieve this by switching async from an init pattern to a constructor. This means moving async fields to pointers, but since they weren't safe to use prior to initialization anyway this feels correct. Change-Id: I4f93980915e0b568fbf2db3cd7d062adf06e4b99 Reviewed-on: https://go-review.googlesource.com/c/tools/+/330929 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
parent
facfa16e73
commit
0c89f898b7
3 changed files with 7 additions and 5 deletions
|
|
@ -50,7 +50,7 @@ type Connection struct {
|
||||||
writerBox chan Writer
|
writerBox chan Writer
|
||||||
outgoingBox chan map[ID]chan<- *Response
|
outgoingBox chan map[ID]chan<- *Response
|
||||||
incomingBox chan map[ID]*incoming
|
incomingBox chan map[ID]*incoming
|
||||||
async async
|
async *async
|
||||||
}
|
}
|
||||||
|
|
||||||
type AsyncCall struct {
|
type AsyncCall struct {
|
||||||
|
|
@ -87,6 +87,7 @@ func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) (
|
||||||
writerBox: make(chan Writer, 1),
|
writerBox: make(chan Writer, 1),
|
||||||
outgoingBox: make(chan map[ID]chan<- *Response, 1),
|
outgoingBox: make(chan map[ID]chan<- *Response, 1),
|
||||||
incomingBox: make(chan map[ID]*incoming, 1),
|
incomingBox: make(chan map[ID]*incoming, 1),
|
||||||
|
async: newAsync(),
|
||||||
}
|
}
|
||||||
|
|
||||||
options, err := binder.Bind(ctx, c)
|
options, err := binder.Bind(ctx, c)
|
||||||
|
|
@ -104,7 +105,6 @@ func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) (
|
||||||
}
|
}
|
||||||
c.outgoingBox <- make(map[ID]chan<- *Response)
|
c.outgoingBox <- make(map[ID]chan<- *Response)
|
||||||
c.incomingBox <- make(map[ID]*incoming)
|
c.incomingBox <- make(map[ID]*incoming)
|
||||||
c.async.init()
|
|
||||||
// the goroutines started here will continue until the underlying stream is closed
|
// the goroutines started here will continue until the underlying stream is closed
|
||||||
reader := options.Framer.Reader(rwc)
|
reader := options.Framer.Reader(rwc)
|
||||||
readToQueue := make(chan *incoming)
|
readToQueue := make(chan *incoming)
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,12 @@ type async struct {
|
||||||
errBox chan error
|
errBox chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *async) init() {
|
func newAsync() *async {
|
||||||
|
var a async
|
||||||
a.ready = make(chan struct{})
|
a.ready = make(chan struct{})
|
||||||
a.errBox = make(chan error, 1)
|
a.errBox = make(chan error, 1)
|
||||||
a.errBox <- nil
|
a.errBox <- nil
|
||||||
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *async) done() {
|
func (a *async) done() {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type Dialer interface {
|
||||||
type Server struct {
|
type Server struct {
|
||||||
listener Listener
|
listener Listener
|
||||||
binder Binder
|
binder Binder
|
||||||
async async
|
async *async
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial uses the dialer to make a new connection, wraps the returned
|
// Dial uses the dialer to make a new connection, wraps the returned
|
||||||
|
|
@ -68,8 +68,8 @@ func Serve(ctx context.Context, listener Listener, binder Binder) (*Server, erro
|
||||||
server := &Server{
|
server := &Server{
|
||||||
listener: listener,
|
listener: listener,
|
||||||
binder: binder,
|
binder: binder,
|
||||||
|
async: newAsync(),
|
||||||
}
|
}
|
||||||
server.async.init()
|
|
||||||
go server.run(ctx)
|
go server.run(ctx)
|
||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue