mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	fix #1119 and data race in timming tasks
This commit is contained in:
		| @@ -17,6 +17,7 @@ import ( | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| @@ -1377,20 +1378,54 @@ func RewriteRepositoryUpdateHook() error { | ||||
| 		}) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// Prevent duplicate running tasks. | ||||
| 	isMirrorUpdating = false | ||||
| 	isGitFscking     = false | ||||
| 	isCheckingRepos  = false | ||||
| // statusPool represents a pool of status with true/false. | ||||
| type statusPool struct { | ||||
| 	lock sync.RWMutex | ||||
| 	pool map[string]bool | ||||
| } | ||||
|  | ||||
| // Start sets value of given name to true in the pool. | ||||
| func (p *statusPool) Start(name string) { | ||||
| 	p.lock.Lock() | ||||
| 	defer p.lock.Unlock() | ||||
|  | ||||
| 	p.pool[name] = true | ||||
| } | ||||
|  | ||||
| // Stop sets value of given name to false in the pool. | ||||
| func (p *statusPool) Stop(name string) { | ||||
| 	p.lock.Lock() | ||||
| 	defer p.lock.Unlock() | ||||
|  | ||||
| 	p.pool[name] = false | ||||
| } | ||||
|  | ||||
| // IsRunning checks if value of given name is set to true in the pool. | ||||
| func (p *statusPool) IsRunning(name string) bool { | ||||
| 	p.lock.RLock() | ||||
| 	defer p.lock.RUnlock() | ||||
|  | ||||
| 	return p.pool[name] | ||||
| } | ||||
|  | ||||
| // Prevent duplicate running tasks. | ||||
| var taskStatusPool = &statusPool{ | ||||
| 	pool: make(map[string]bool), | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	_MIRROR_UPDATE = "mirror_update" | ||||
| 	_GIT_FSCK      = "git_fsck" | ||||
| 	_CHECK_REPOs   = "check_repos" | ||||
| ) | ||||
|  | ||||
| // MirrorUpdate checks and updates mirror repositories. | ||||
| func MirrorUpdate() { | ||||
| 	if isMirrorUpdating { | ||||
| 	if taskStatusPool.IsRunning(_MIRROR_UPDATE) { | ||||
| 		return | ||||
| 	} | ||||
| 	isMirrorUpdating = true | ||||
| 	defer func() { isMirrorUpdating = false }() | ||||
| 	taskStatusPool.Start(_MIRROR_UPDATE) | ||||
| 	defer taskStatusPool.Stop(_MIRROR_UPDATE) | ||||
|  | ||||
| 	log.Trace("Doing: MirrorUpdate") | ||||
|  | ||||
| @@ -1438,11 +1473,11 @@ func MirrorUpdate() { | ||||
|  | ||||
| // GitFsck calls 'git fsck' to check repository health. | ||||
| func GitFsck() { | ||||
| 	if isGitFscking { | ||||
| 	if taskStatusPool.IsRunning(_GIT_FSCK) { | ||||
| 		return | ||||
| 	} | ||||
| 	isGitFscking = true | ||||
| 	defer func() { isGitFscking = false }() | ||||
| 	taskStatusPool.Start(_GIT_FSCK) | ||||
| 	defer taskStatusPool.Stop(_GIT_FSCK) | ||||
|  | ||||
| 	log.Trace("Doing: GitFsck") | ||||
|  | ||||
| @@ -1507,11 +1542,11 @@ func repoStatsCheck(checker *repoChecker) { | ||||
| } | ||||
|  | ||||
| func CheckRepoStats() { | ||||
| 	if isCheckingRepos { | ||||
| 	if taskStatusPool.IsRunning(_CHECK_REPOs) { | ||||
| 		return | ||||
| 	} | ||||
| 	isCheckingRepos = true | ||||
| 	defer func() { isCheckingRepos = false }() | ||||
| 	taskStatusPool.Start(_CHECK_REPOs) | ||||
| 	defer taskStatusPool.Stop(_CHECK_REPOs) | ||||
|  | ||||
| 	log.Trace("Doing: CheckRepoStats") | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,28 @@ type Tree struct { | ||||
| 	entriesParsed bool | ||||
| } | ||||
|  | ||||
| var escapeChar = []byte("\\") | ||||
|  | ||||
| func unescapeChars(in []byte) []byte { | ||||
| 	if bytes.Index(in, escapeChar) == -1 { | ||||
| 		return in | ||||
| 	} | ||||
|  | ||||
| 	endIdx := len(in) - 1 | ||||
| 	isEscape := false | ||||
| 	out := make([]byte, 0, endIdx+1) | ||||
| 	for i := range in { | ||||
| 		if in[i] == '\\' && i != endIdx { | ||||
| 			isEscape = !isEscape | ||||
| 			if isEscape { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		out = append(out, in[i]) | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // Parse tree information from the (uncompressed) raw | ||||
| // data from the tree object. | ||||
| func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) { | ||||
| @@ -74,8 +96,7 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) { | ||||
|  | ||||
| 		// In case entry name is surrounded by double quotes(it happens only in git-shell). | ||||
| 		if entry.name[0] == '"' { | ||||
| 			entry.name = string(data[pos+1 : pos+step-1]) | ||||
| 			entry.name = strings.Replace(entry.name, `\"`, `"`, -1) | ||||
| 			entry.name = string(unescapeChars(data[pos+1 : pos+step-1])) | ||||
| 		} | ||||
|  | ||||
| 		pos += step + 1 | ||||
|   | ||||
| @@ -319,6 +319,9 @@ func Profile(ctx *middleware.Context) { | ||||
| 	if uname == "favicon.ico" { | ||||
| 		ctx.Redirect(setting.AppSubUrl + "/img/favicon.png") | ||||
| 		return | ||||
| 	} else if strings.HasSuffix(uname, ".png") { | ||||
| 		ctx.Error(404) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	isShowKeys := false | ||||
|   | ||||
		Reference in New Issue
	
	Block a user