mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Reduce data races (#14549)
* Add race conditions into test * Fix Race in GetManager() * DataAsync() use error chan * just log no chan * finish
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user