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:
parent
76c7548162
commit
98a5f52ef0
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user