Skip to content

Commit

Permalink
fix concurrent SetError in pin command
Browse files Browse the repository at this point in the history
(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>
  • Loading branch information
Stebalien committed Nov 21, 2017
1 parent a62eb62 commit 5012c6a
Showing 1 changed file with 10 additions and 11 deletions.
21 changes: 10 additions & 11 deletions core/commands/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,32 +90,31 @@ var addPinCmd = &cmds.Command{
v := new(dag.ProgressTracker)
ctx := v.DeriveContext(req.Context())

ch := make(chan []*cid.Cid)
type pinResult struct {
pins []*cid.Cid
err error
}
ch := make(chan pinResult, 1)
go func() {
defer close(ch)
added, err := corerepo.Pin(n, ctx, req.Arguments(), recursive)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
ch <- added
ch <- pinResult{pins: added, err: err}
}()

ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
defer close(out)
for {
select {
case val, ok := <-ch:
if !ok {
// error already set just return
case val := <-ch:
if val.err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

if pv := v.Value(); pv != 0 {
out <- &AddPinOutput{Progress: v.Value()}
}
out <- &AddPinOutput{Pins: cidsToStrings(val)}
out <- &AddPinOutput{Pins: cidsToStrings(val.pins)}
return
case <-ticker.C:
out <- &AddPinOutput{Progress: v.Value()}
Expand Down

0 comments on commit 5012c6a

Please sign in to comment.