Skip to content

Commit b120c10

Browse files
authored
os: make os.cache_dir() and os.vtmp_dir() more robust to parallel test executions on windows (#20495)
1 parent d986f82 commit b120c10

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

vlib/os/os.v

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,21 @@ pub fn mkdir_all(opath string, params MkdirParams) ! {
738738
}
739739
}
740740

741+
fn create_folder_when_it_does_not_exist(path string) {
742+
if is_dir(path) || is_link(path) {
743+
return
744+
}
745+
mkdir_all(path, mode: 0o700) or {
746+
if is_dir(path) || is_link(path) {
747+
// A race had been won, and the `path` folder had been created,
748+
// by another concurrent V executable, since the folder now exists,
749+
// but it did not right before ... we will just use it too.
750+
return
751+
}
752+
panic(err)
753+
}
754+
}
755+
741756
// cache_dir returns the path to a *writable* user specific folder, suitable for writing non-essential data.
742757
pub fn cache_dir() string {
743758
// See: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
@@ -748,16 +763,12 @@ pub fn cache_dir() string {
748763
// non-essential data files should be stored. If $XDG_CACHE_HOME is either not set
749764
// or empty, a default equal to $HOME/.cache should be used.
750765
xdg_cache_home := getenv('XDG_CACHE_HOME')
751-
if xdg_cache_home != '' {
752-
if !is_dir(xdg_cache_home) && !is_link(xdg_cache_home) {
753-
mkdir_all(xdg_cache_home, mode: 0o700) or { panic(err) }
754-
}
755-
return xdg_cache_home
756-
}
757-
cdir := join_path_single(home_dir(), '.cache')
758-
if !is_dir(cdir) && !is_link(cdir) {
759-
mkdir(cdir) or { panic(err) }
766+
cdir := if xdg_cache_home.len > 0 {
767+
xdg_cache_home
768+
} else {
769+
join_path_single(home_dir(), '.cache')
760770
}
771+
create_folder_when_it_does_not_exist(cdir)
761772
return cdir
762773
}
763774

@@ -803,14 +814,12 @@ pub fn temp_dir() string {
803814
pub fn vtmp_dir() string {
804815
mut vtmp := getenv('VTMP')
805816
if vtmp.len > 0 {
817+
create_folder_when_it_does_not_exist(vtmp)
806818
return vtmp
807819
}
808820
uid := getuid()
809821
vtmp = join_path_single(temp_dir(), 'v_${uid}')
810-
if !exists(vtmp) || !is_dir(vtmp) {
811-
// create a new directory, that is private to the user:
812-
mkdir_all(vtmp, mode: 0o700) or { panic(err) }
813-
}
822+
create_folder_when_it_does_not_exist(vtmp)
814823
setenv('VTMP', vtmp, true)
815824
return vtmp
816825
}

0 commit comments

Comments
 (0)