]> source.dussan.org Git - gitea.git/commitdiff
Reduce data races (#14549)
author6543 <6543@obermui.de>
Wed, 3 Feb 2021 21:36:38 +0000 (22:36 +0100)
committerGitHub <noreply@github.com>
Wed, 3 Feb 2021 21:36:38 +0000 (22:36 +0100)
* Add race conditions into test

* Fix Race in GetManager()

* DataAsync() use error chan

* just log no chan

* finish

modules/git/blob_nogogit.go
modules/process/manager.go
modules/process/manager_test.go

index 401b172860ee6ea66cd45e5720d615942255f4eb..731f7d06e8a608a314c2ba4bc21f3d63e57aaab6 100644 (file)
@@ -11,6 +11,8 @@ import (
        "io"
        "strconv"
        "strings"
+
+       gitea_log "code.gitea.io/gitea/modules/log"
 )
 
 // Blob represents a Git object.
@@ -27,13 +29,13 @@ type Blob struct {
 // Calling the Close function on the result will discard all unread output.
 func (b *Blob) DataAsync() (io.ReadCloser, error) {
        stdoutReader, stdoutWriter := io.Pipe()
-       var err error
 
        go func() {
                stderr := &strings.Builder{}
-               err = NewCommand("cat-file", "--batch").RunInDirFullPipeline(b.repoPath, stdoutWriter, stderr, strings.NewReader(b.ID.String()+"\n"))
+               err := NewCommand("cat-file", "--batch").RunInDirFullPipeline(b.repoPath, stdoutWriter, stderr, strings.NewReader(b.ID.String()+"\n"))
                if err != nil {
                        err = ConcatenateError(err, stderr.String())
+                       gitea_log.Error("Blob.DataAsync Error: %v", err)
                        _ = stdoutWriter.CloseWithError(err)
                } else {
                        _ = stdoutWriter.Close()
@@ -50,8 +52,8 @@ func (b *Blob) DataAsync() (io.ReadCloser, error) {
        return &LimitedReaderCloser{
                R: bufReader,
                C: stdoutReader,
-               N: int64(size),
-       }, err
+               N: size,
+       }, nil
 }
 
 // Size returns the uncompressed size of the blob
index 27ed1d4964d15589e87d4bee204bff93750aa3ad..9d57f4eb7b903880656ec7dbd6438fac8b854f0c 100644 (file)
@@ -25,6 +25,7 @@ var (
        // ErrExecTimeout represent a timeout error
        ErrExecTimeout = errors.New("Process execution timeout")
        manager        *Manager
+       managerInit    sync.Once
 
        // DefaultContext is the default context to run processing commands in
        DefaultContext = context.Background()
@@ -48,11 +49,11 @@ type Manager struct {
 
 // GetManager returns a Manager and initializes one as singleton if there's none yet
 func GetManager() *Manager {
-       if manager == nil {
+       managerInit.Do(func() {
                manager = &Manager{
                        processes: make(map[int64]*Process),
                }
-       }
+       })
        return manager
 }
 
index 42f4b0c04b5a15aab0eff60f9227f6afdafdab92..a515fc32cda71f5fb6e5f659d7755ee81a8f373e 100644 (file)
@@ -12,6 +12,15 @@ import (
        "github.com/stretchr/testify/assert"
 )
 
+func TestGetManager(t *testing.T) {
+       go func() {
+               // test race protection
+               _ = GetManager()
+       }()
+       pm := GetManager()
+       assert.NotNil(t, pm)
+}
+
 func TestManager_Add(t *testing.T) {
        pm := Manager{processes: make(map[int64]*Process)}