]> source.dussan.org Git - gitea.git/commitdiff
fix #1119 and data race in timming tasks
authorUnknwon <u@gogs.io>
Fri, 20 Nov 2015 05:47:35 +0000 (00:47 -0500)
committerUnknwon <u@gogs.io>
Fri, 20 Nov 2015 05:47:35 +0000 (00:47 -0500)
models/repo.go
modules/git/tree.go
routers/user/home.go

index 1521f1e0632cbf494525cc469059d2a735708833..800094098b5bc078b452939e66a73d2e851e04af 100644 (file)
@@ -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")
 
index cc62a2d52814ec40332a5ebda34a3e75741a858e..6cfdbf47c2e078f6bbfa3d166e739828ab727989 100644 (file)
@@ -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
index 98033fc17dc79623b867050d4498068fc2d97e3b..96202ed0801e2d6a9ae0e932ecce857823b785a7 100644 (file)
@@ -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