From dbfbc3d3163db6e2831ede1de16b0be2aad638c3 Mon Sep 17 00:00:00 2001
From: a <a@tuxpa.in>
Date: Sat, 5 Aug 2023 17:35:09 -0500
Subject: [PATCH] fix race

---
 contrib/codecs/rdwr/client.go | 11 +++++++----
 pkg/server/server.go          | 15 +++++----------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/contrib/codecs/rdwr/client.go b/contrib/codecs/rdwr/client.go
index dcc6a65..cee08fc 100644
--- a/contrib/codecs/rdwr/client.go
+++ b/contrib/codecs/rdwr/client.go
@@ -1,7 +1,6 @@
 package rdwr
 
 import (
-	"bytes"
 	"context"
 	"encoding/json"
 	"io"
@@ -9,6 +8,7 @@ import (
 
 	"gfx.cafe/open/jrpc/pkg/clientutil"
 	"gfx.cafe/open/jrpc/pkg/codec"
+	"gfx.cafe/util/go/bufpool"
 )
 
 type Client struct {
@@ -106,15 +106,17 @@ func (c *Client) listen() error {
 
 func (c *Client) Do(ctx context.Context, result any, method string, params any) error {
 	id := c.p.NextId()
+	buf := bufpool.GetStd()
+	defer bufpool.PutStd(buf)
 	req, err := codec.NewRequest(ctx, codec.NewId(id), method, params)
 	if err != nil {
 		return err
 	}
-	fwd, err := json.Marshal(req)
+	err = json.NewEncoder(buf).Encode(req)
 	if err != nil {
 		return err
 	}
-	err = c.writeContext(req.Context(), fwd)
+	err = c.writeContext(req.Context(), buf.Bytes())
 	if err != nil {
 		return err
 	}
@@ -135,7 +137,8 @@ func (c *Client) BatchCall(ctx context.Context, b ...*codec.BatchElem) error {
 	if ctx == nil {
 		ctx = context.Background()
 	}
-	buf := new(bytes.Buffer)
+	buf := bufpool.GetStd()
+	defer bufpool.PutStd(buf)
 	enc := json.NewEncoder(buf)
 	reqs := make([]*codec.Request, 0, len(b))
 	ids := make([]*codec.ID, 0, len(b))
diff --git a/pkg/server/server.go b/pkg/server/server.go
index 62ee9b5..8501f24 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -154,19 +154,14 @@ func (s *Server) ServeCodec(pctx context.Context, remote codec.ReaderWriter) {
 		if err != nil {
 			s.printError(remote, err)
 		}
-		// lose
-		err = remote.Close()
-		if err != nil {
-			s.printError(remote, err)
-		}
-	}()
-
-	go func() {
-		<-ctx.Done()
-		remote.Close()
 	}()
 
 	for {
+		select {
+		case <-ctx.Done():
+			remote.Close()
+		default:
+		}
 		err := s.codecLoop(ctx, remote, responder)
 		if err != nil {
 			s.printError(remote, err)
-- 
GitLab