1
0
mirror of https://github.com/golang/go synced 2024-11-23 04:40:09 -07:00

os: avoid error result when dir is removed out from under RemoveAll

Fixes #7776.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews, r
https://golang.org/cl/145860043
This commit is contained in:
Russ Cox 2014-09-18 14:48:47 -04:00
parent 76c7548162
commit 98a5f52ef0
2 changed files with 46 additions and 1 deletions

View File

@ -18,6 +18,7 @@ import (
"runtime"
"sort"
"strings"
"sync"
"syscall"
"testing"
"text/template"
@ -1403,3 +1404,44 @@ func TestNilFileMethods(t *testing.T) {
}
}
}
func mkdirTree(t *testing.T, root string, level, max int) {
if level >= max {
return
}
level++
for i := 'a'; i < 'c'; i++ {
dir := filepath.Join(root, string(i))
if err := Mkdir(dir, 0700); err != nil {
t.Fatal(err)
}
mkdirTree(t, dir, level, max)
}
}
// Test that simultaneous RemoveAll do not report an error.
// As long as it gets removed, we should be happy.
func TestRemoveAllRace(t *testing.T) {
n := runtime.GOMAXPROCS(16)
defer runtime.GOMAXPROCS(n)
root, err := ioutil.TempDir("", "issue")
if err != nil {
t.Fatal(err)
}
mkdirTree(t, root, 1, 6)
hold := make(chan struct{})
var wg sync.WaitGroup
for i := 0; i < 4; i++ {
wg.Add(1)
go func() {
defer wg.Done()
<-hold
err := RemoveAll(root)
if err != nil {
t.Errorf("unexpected error: %T, %q", err, err)
}
}()
}
close(hold) // let workers race to remove root
wg.Wait()
}

View File

@ -66,7 +66,7 @@ func MkdirAll(path string, perm FileMode) error {
func RemoveAll(path string) error {
// Simple case: if Remove works, we're done.
err := Remove(path)
if err == nil {
if err == nil || IsNotExist(err) {
return nil
}
@ -116,6 +116,9 @@ func RemoveAll(path string) error {
// Remove directory.
err1 := Remove(path)
if err1 == nil || IsNotExist(err1) {
return nil
}
if err == nil {
err = err1
}