Skip to content

Commit

Permalink
Fix status table race condition (go-gitea#1835)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethantkoenig authored and lunny committed May 31, 2017
1 parent 0f5b399 commit bfb44f8
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 10 deletions.
9 changes: 3 additions & 6 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -1881,10 +1881,9 @@ func DeleteRepositoryArchives() error {

// DeleteOldRepositoryArchives deletes old repository archives.
func DeleteOldRepositoryArchives() {
if taskStatusTable.IsRunning(archiveCleanup) {
if !taskStatusTable.StartIfNotRunning(archiveCleanup) {
return
}
taskStatusTable.Start(archiveCleanup)
defer taskStatusTable.Stop(archiveCleanup)

log.Trace("Doing: ArchiveCleanup")
Expand Down Expand Up @@ -2025,10 +2024,9 @@ const (

// GitFsck calls 'git fsck' to check repository health.
func GitFsck() {
if taskStatusTable.IsRunning(gitFsck) {
if !taskStatusTable.StartIfNotRunning(gitFsck) {
return
}
taskStatusTable.Start(gitFsck)
defer taskStatusTable.Stop(gitFsck)

log.Trace("Doing: GitFsck")
Expand Down Expand Up @@ -2097,10 +2095,9 @@ func repoStatsCheck(checker *repoChecker) {

// CheckRepoStats checks the repository stats
func CheckRepoStats() {
if taskStatusTable.IsRunning(checkRepos) {
if !taskStatusTable.StartIfNotRunning(checkRepos) {
return
}
taskStatusTable.Start(checkRepos)
defer taskStatusTable.Stop(checkRepos)

log.Trace("Doing: CheckRepoStats")
Expand Down
3 changes: 1 addition & 2 deletions models/repo_mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,9 @@ func DeleteMirrorByRepoID(repoID int64) error {

// MirrorUpdate checks and updates mirror repositories.
func MirrorUpdate() {
if taskStatusTable.IsRunning(mirrorUpdate) {
if !taskStatusTable.StartIfNotRunning(mirrorUpdate) {
return
}
taskStatusTable.Start(mirrorUpdate)
defer taskStatusTable.Stop(mirrorUpdate)

log.Trace("Doing: MirrorUpdate")
Expand Down
3 changes: 1 addition & 2 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -1334,10 +1334,9 @@ func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) {

// SyncExternalUsers is used to synchronize users with external authorization source
func SyncExternalUsers() {
if taskStatusTable.IsRunning(syncExternalUsers) {
if !taskStatusTable.StartIfNotRunning(syncExternalUsers) {
return
}
taskStatusTable.Start(syncExternalUsers)
defer taskStatusTable.Stop(syncExternalUsers)

log.Trace("Doing: SyncExternalUsers")
Expand Down
12 changes: 12 additions & 0 deletions modules/sync/status_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ func NewStatusTable() *StatusTable {
}
}

// StartIfNotRunning sets value of given name to true if not already in pool.
// Returns whether set value was set to true
func (p *StatusTable) StartIfNotRunning(name string) bool {
p.lock.Lock()
_, ok := p.pool[name]
if !ok {
p.pool[name] = struct{}{}
}
p.lock.Unlock()
return !ok
}

// Start sets value of given name to true in the pool.
func (p *StatusTable) Start(name string) {
p.lock.Lock()
Expand Down
9 changes: 9 additions & 0 deletions modules/sync/status_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ func Test_StatusTable(t *testing.T) {
table.Start("xyz")
assert.True(t, table.IsRunning("xyz"))

assert.False(t, table.StartIfNotRunning("xyz"))
assert.True(t, table.IsRunning("xyz"))

table.Stop("xyz")
assert.False(t, table.IsRunning("xyz"))

assert.True(t, table.StartIfNotRunning("xyz"))
assert.True(t, table.IsRunning("xyz"))

table.Stop("xyz")
assert.False(t, table.IsRunning("xyz"))
}

0 comments on commit bfb44f8

Please sign in to comment.