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:
Delyan Angelov 2024-10-17 15:51:04 +03:00 committed by GitHub
parent 8556353b43
commit 7da79fd221
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 7 deletions

View file

@ -800,15 +800,27 @@ fn create_folder_when_it_does_not_exist(path string) {
if is_dir(path) || is_link(path) {
return
}
mut error_msg := ''
for _ in 0 .. 10 {
mkdir_all(path, mode: 0o700) or {
if is_dir(path) || is_link(path) {
// A race had been won, and the `path` folder had been created,
// by another concurrent V executable, since the folder now exists,
// 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.
// 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
}
panic(err)
error_msg = err.msg()
sleep_ms(1) // wait a bit, before a retry, to let the other process finish its folder creation
continue
}
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 {

26
vlib/os/sleeping.c.v Normal file
View 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
View 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)) {}
}