mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
os: improve robustness of create_folder_when_it_does_not_exist/1 (fix CI false positives for vab-compiles-v-examples
) (#22548)
This commit is contained in:
parent
8556353b43
commit
7da79fd221
3 changed files with 53 additions and 7 deletions
26
vlib/os/os.v
26
vlib/os/os.v
|
@ -800,15 +800,27 @@ fn create_folder_when_it_does_not_exist(path string) {
|
||||||
if is_dir(path) || is_link(path) {
|
if is_dir(path) || is_link(path) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mkdir_all(path, mode: 0o700) or {
|
mut error_msg := ''
|
||||||
if is_dir(path) || is_link(path) {
|
for _ in 0 .. 10 {
|
||||||
// A race had been won, and the `path` folder had been created,
|
mkdir_all(path, mode: 0o700) or {
|
||||||
// by another concurrent V executable, since the folder now exists,
|
if is_dir(path) || is_link(path) {
|
||||||
// but it did not right before ... we will just use it too.
|
// A race had been won, and the `path` folder had been created, by another concurrent V program.
|
||||||
return
|
// We are fine with that, since the folder now exists, even though this process did not create it.
|
||||||
|
// We can just use it too ¯\_(ツ)_/¯ .
|
||||||
|
return
|
||||||
|
}
|
||||||
|
error_msg = err.msg()
|
||||||
|
sleep_ms(1) // wait a bit, before a retry, to let the other process finish its folder creation
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
panic(err)
|
break
|
||||||
}
|
}
|
||||||
|
if is_dir(path) || is_link(path) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// There was something wrong, that could not be solved, by just retrying
|
||||||
|
// There is no choice, but to report it back :-\
|
||||||
|
panic(error_msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn xdg_home_folder(ename string, lpath string) string {
|
fn xdg_home_folder(ename string, lpath string) string {
|
||||||
|
|
26
vlib/os/sleeping.c.v
Normal file
26
vlib/os/sleeping.c.v
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module os
|
||||||
|
|
||||||
|
pub struct C.timespec {
|
||||||
|
pub mut:
|
||||||
|
tv_sec i64
|
||||||
|
tv_nsec i64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn C.nanosleep(req &C.timespec, rem &C.timespec) int
|
||||||
|
|
||||||
|
// sleep_ms provides a cross platform way to sleep, without having to `import time` for a time.sleep/1 call.
|
||||||
|
fn sleep_ms(ms i64) {
|
||||||
|
$if windows {
|
||||||
|
C.Sleep(u32(ms))
|
||||||
|
} $else {
|
||||||
|
mut req := C.timespec{ms / 1000, 1_000_000 * (ms % 1000)}
|
||||||
|
rem := C.timespec{}
|
||||||
|
for C.nanosleep(&req, &rem) < 0 {
|
||||||
|
if C.errno == C.EINTR {
|
||||||
|
req = rem
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
vlib/os/sleeping.js.v
Normal file
8
vlib/os/sleeping.js.v
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module os
|
||||||
|
|
||||||
|
// sleep_ms suspends the execution for a given duration (in milliseconds), without having to `import time` for a single time.sleep/1 call.
|
||||||
|
fn sleep_ms(dur i64) {
|
||||||
|
#let now = new Date().getTime()
|
||||||
|
#let toWait = BigInt(dur)
|
||||||
|
#while (new Date().getTime() < now + Number(toWait)) {}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue