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
|
||||
outgoingBox chan map[ID]chan<- *Response
|
||||
incomingBox chan map[ID]*incoming
|
||||
async async
|
||||
async *async
|
||||
}
|
||||
|
||||
type AsyncCall struct {
|
||||
|
|
@ -87,6 +87,7 @@ func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) (
|
|||
writerBox: make(chan Writer, 1),
|
||||
outgoingBox: make(chan map[ID]chan<- *Response, 1),
|
||||
incomingBox: make(chan map[ID]*incoming, 1),
|
||||
async: newAsync(),
|
||||
}
|
||||
|
||||
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.incomingBox <- make(map[ID]*incoming)
|
||||
c.async.init()
|
||||
// the goroutines started here will continue until the underlying stream is closed
|
||||
reader := options.Framer.Reader(rwc)
|
||||
readToQueue := make(chan *incoming)
|
||||
|
|
|
|||
|
|
@ -64,10 +64,12 @@ type async struct {
|
|||
errBox chan error
|
||||
}
|
||||
|
||||
func (a *async) init() {
|
||||
func newAsync() *async {
|
||||
var a async
|
||||
a.ready = make(chan struct{})
|
||||
a.errBox = make(chan error, 1)
|
||||
a.errBox <- nil
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a *async) done() {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ type Dialer interface {
|
|||
type Server struct {
|
||||
listener Listener
|
||||
binder Binder
|
||||
async async
|
||||
async *async
|
||||
}
|
||||
|
||||
// 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{
|
||||
listener: listener,
|
||||
binder: binder,
|
||||
async: newAsync(),
|
||||
}
|
||||
server.async.init()
|
||||
go server.run(ctx)
|
||||
return server, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue