diff --git a/internal/jsonrpc2/conn.go b/internal/jsonrpc2/conn.go index b7ebc68..91f0b56 100644 --- a/internal/jsonrpc2/conn.go +++ b/internal/jsonrpc2/conn.go @@ -112,6 +112,7 @@ func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) ( go c.readIncoming(ctx, reader, readToQueue) go c.manageQueue(ctx, options.Preempter, readToQueue, queueToDeliver) go c.deliverMessages(ctx, options.Handler, queueToDeliver) + // releaseing the writer must be the last thing we do in case any requests // are blocked waiting for the connection to be ready c.writerBox <- options.Framer.Writer(rwc) diff --git a/internal/jsonrpc2/jsonrpc2.go b/internal/jsonrpc2/jsonrpc2.go index 8f5f040..f38b6cb 100644 --- a/internal/jsonrpc2/jsonrpc2.go +++ b/internal/jsonrpc2/jsonrpc2.go @@ -57,11 +57,11 @@ func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, err return f(ctx, req) } -// async is a small helper for things with an asynchronous result that you can -// wait for. +// async is a small helper for operations with an asynchronous result that you +// can wait for. type async struct { - ready chan struct{} - errBox chan error + ready chan struct{} // signals that the operation has completed + errBox chan error // guards the operation result } func newAsync() *async { diff --git a/internal/jsonrpc2/jsonrpc2_test.go b/internal/jsonrpc2/jsonrpc2_test.go index 9fce9ea..5f0674f 100644 --- a/internal/jsonrpc2/jsonrpc2_test.go +++ b/internal/jsonrpc2/jsonrpc2_test.go @@ -126,7 +126,7 @@ func TestConnectionHeader(t *testing.T) { func testConnection(t *testing.T, framer jsonrpc2.Framer) { stacktest.NoLeak(t) ctx := eventtest.NewContext(context.Background(), t) - listener, err := jsonrpc2.NetPipe(ctx) + listener, err := jsonrpc2.NetPipeListener(ctx) if err != nil { t.Fatal(err) } diff --git a/internal/jsonrpc2/net.go b/internal/jsonrpc2/net.go index beb12f8..76f1b7d 100644 --- a/internal/jsonrpc2/net.go +++ b/internal/jsonrpc2/net.go @@ -80,11 +80,11 @@ func (n *netDialer) Dial(ctx context.Context) (io.ReadWriteCloser, error) { return n.dialer.DialContext(ctx, n.network, n.address) } -// NetPipe returns a new Listener that listens using net.Pipe. +// NetPipeListener returns a new Listener that listens using net.Pipe. // It is only possibly to connect to it using the Dialier returned by the // Dialer method, each call to that method will generate a new pipe the other // side of which will be returnd from the Accept call. -func NetPipe(ctx context.Context) (Listener, error) { +func NetPipeListener(ctx context.Context) (Listener, error) { return &netPiper{ done: make(chan struct{}), dialed: make(chan io.ReadWriteCloser), diff --git a/internal/jsonrpc2/serve_test.go b/internal/jsonrpc2/serve_test.go index d1c119e..0e77aab 100644 --- a/internal/jsonrpc2/serve_test.go +++ b/internal/jsonrpc2/serve_test.go @@ -89,7 +89,7 @@ func TestServe(t *testing.T) { return jsonrpc2.NetListener(ctx, "tcp", "localhost:0", jsonrpc2.NetListenOptions{}) }}, {"pipe", func(ctx context.Context) (jsonrpc2.Listener, error) { - return jsonrpc2.NetPipe(ctx) + return jsonrpc2.NetPipeListener(ctx) }}, }