fix concurrent SetError in pin command
(segfault) Also, buffer the response channel. I believe we had a go routine leak here before. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>
Steven Allen committed
Nov 20, 2017 at 19:43 UTC
65489c1744410850c1c6221ca9c6d42479776515
1 file changed
+10
-11
core/commands/pin.go
+10
-11
@@ -90,15 +90,14 @@ var addPinCmd = &cmds.Command{
90
v := new(dag.ProgressTracker)
91
ctx := v.DeriveContext(req.Context())
92
93
- ch := make(chan []*cid.Cid)
93
+ type pinResult struct {
94
+ pins []*cid.Cid
95
+ err error
96
+ }
97
+ ch := make(chan pinResult, 1)
98
go func() {
95
- defer close(ch)
99
added, err := corerepo.Pin(n, ctx, req.Arguments(), recursive)
97
- if err != nil {
98
- res.SetError(err, cmdkit.ErrNormal)
99
- return
100
- }
101
- ch <- added
100
+ ch <- pinResult{pins: added, err: err}
101
}()
102
103
ticker := time.NewTicker(500 * time.Millisecond)
@@ -106,16 +105,16 @@ var addPinCmd = &cmds.Command{
105
defer close(out)
106
for {
107
select {
109
- case val, ok := <-ch:
110
- if !ok {
111
- // error already set just return
108
+ case val := <-ch:
109
+ if val.err != nil {
110
+ res.SetError(val.err, cmdkit.ErrNormal)
111
return
112
}
113
114
if pv := v.Value(); pv != 0 {
115
out <- &AddPinOutput{Progress: v.Value()}
116
}
118
- out <- &AddPinOutput{Pins: cidsToStrings(val)}
117
+ out <- &AddPinOutput{Pins: cidsToStrings(val.pins)}
118
return
119
case <-ticker.C:
120
out <- &AddPinOutput{Progress: v.Value()}