Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit fae29fb

Browse files
committed
git: fix goroutine block while pushing a remote
On session.ReceivePack error the gororutine doing the encoding got blocked either writing objects to the pipe or sending error to the done channel. The problem did not cause a perceived problem but left blocked goroutines. Signed-off-by: Javi Fontan <jfontan@gmail.com>
1 parent 0106dab commit fae29fb

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

remote.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,12 @@ func pushHashes(
10201020
if err != nil {
10211021
return nil, err
10221022
}
1023-
done := make(chan error)
1023+
1024+
// Set buffer size to 1 so the error message can be written when
1025+
// ReceivePack fails. Otherwise the goroutine will be blocked writing
1026+
// to the channel.
1027+
done := make(chan error, 1)
1028+
10241029
go func() {
10251030
e := packfile.NewEncoder(wr, s, useRefDeltas)
10261031
if _, err := e.Encode(hs, config.Pack.Window); err != nil {
@@ -1033,6 +1038,8 @@ func pushHashes(
10331038

10341039
rs, err := sess.ReceivePack(ctx, req)
10351040
if err != nil {
1041+
// close the pipe to unlock encode write
1042+
_ = rd.Close()
10361043
return nil, err
10371044
}
10381045

remote_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"io"
77
"io/ioutil"
88
"os"
9+
"runtime"
10+
"time"
911

1012
"gopkg.in/src-d/go-git.v4/config"
1113
"gopkg.in/src-d/go-git.v4/plumbing"
@@ -448,10 +450,17 @@ func (s *RemoteSuite) TestPushContext(c *C) {
448450
ctx, cancel := context.WithCancel(context.Background())
449451
cancel()
450452

453+
numGoroutines := runtime.NumGoroutine()
454+
451455
err = r.PushContext(ctx, &PushOptions{
452456
RefSpecs: []config.RefSpec{"refs/tags/*:refs/tags/*"},
453457
})
454458
c.Assert(err, NotNil)
459+
460+
// let the goroutine from pushHashes finish and check that the number of
461+
// goroutines is the same as before
462+
time.Sleep(100 * time.Millisecond)
463+
c.Assert(runtime.NumGoroutine(), Equals, numGoroutines)
455464
}
456465

457466
func (s *RemoteSuite) TestPushTags(c *C) {

0 commit comments

Comments
 (0)