From 03ca08d9bfab9d707c9eef86652690a4534f6e3d Mon Sep 17 00:00:00 2001 From: wanghui Date: Wed, 30 Oct 2019 18:23:13 +0800 Subject: [PATCH 1/3] fix panic when close miner --- lib/jsonrpc/client.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/jsonrpc/client.go b/lib/jsonrpc/client.go index 360e36aef..cb144de77 100644 --- a/lib/jsonrpc/client.go +++ b/lib/jsonrpc/client.go @@ -137,6 +137,7 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) // unpack chan type to make sure it's reflect.BothDir ctyp := reflect.ChanOf(reflect.BothDir, ftyp.Out(valOut).Elem()) ch := reflect.MakeChan(ctyp, 0) // todo: buffer? + chCtx, chCancel := context.WithCancel(ctx) retVal = ch.Convert(ftyp.Out(valOut)) buf := (&list.List{}).Init() @@ -144,6 +145,7 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) return ctx, func(result []byte, ok bool) { if !ok { + chCancel() // remote channel closed, close ours too ch.Close() return @@ -172,14 +174,18 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) go func() { for buf.Len() > 0 { - front := buf.Front() + select { + case <- chCtx.Done(): + buf.Init() + default: + front := buf.Front() + bufLk.Unlock() - bufLk.Unlock() + ch.Send(front.Value.(reflect.Value).Elem()) - ch.Send(front.Value.(reflect.Value).Elem()) // todo: select on ctx is probably a good idea - - bufLk.Lock() - buf.Remove(front) + bufLk.Lock() + buf.Remove(front) + } } bufLk.Unlock() From 8cb14335c3220a047a5bc5a5cc700ca2c0d4ad29 Mon Sep 17 00:00:00 2001 From: wanghui Date: Thu, 31 Oct 2019 13:11:10 +0800 Subject: [PATCH 2/3] use reflect select --- lib/jsonrpc/client.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/jsonrpc/client.go b/lib/jsonrpc/client.go index cb144de77..126da7d04 100644 --- a/lib/jsonrpc/client.go +++ b/lib/jsonrpc/client.go @@ -174,15 +174,26 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) go func() { for buf.Len() > 0 { - select { - case <- chCtx.Done(): + front := buf.Front() + bufLk.Unlock() + + cases := []reflect.SelectCase{ + { + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(chCtx.Done()), + }, + { + Dir: reflect.SelectSend, + Chan: ch, + Send: front.Value.(reflect.Value).Elem(), + }, + } + + switch chosen, _, _ := reflect.Select(cases); chosen { + case 0: + bufLk.Lock() buf.Init() - default: - front := buf.Front() - bufLk.Unlock() - - ch.Send(front.Value.(reflect.Value).Elem()) - + case 1: bufLk.Lock() buf.Remove(front) } From 2aa8eebb993e36712141d4a6b80d5f88c9d5a86f Mon Sep 17 00:00:00 2001 From: wanghui Date: Thu, 31 Oct 2019 17:39:42 +0800 Subject: [PATCH 3/3] move select --- lib/jsonrpc/client.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/jsonrpc/client.go b/lib/jsonrpc/client.go index 126da7d04..81cf4ec0a 100644 --- a/lib/jsonrpc/client.go +++ b/lib/jsonrpc/client.go @@ -189,12 +189,13 @@ func (c *client) makeOutChan(ctx context.Context, ftyp reflect.Type, valOut int) }, } - switch chosen, _, _ := reflect.Select(cases); chosen { + chosen, _, _ := reflect.Select(cases) + bufLk.Lock() + + switch chosen { case 0: - bufLk.Lock() buf.Init() case 1: - bufLk.Lock() buf.Remove(front) } }