diff --git a/vlib/os/os.v b/vlib/os/os.v index d7a0fa22ad..e2cd8d11a5 100644 --- a/vlib/os/os.v +++ b/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) { return } - 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. - 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 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 + } + 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 { diff --git a/vlib/os/sleeping.c.v b/vlib/os/sleeping.c.v new file mode 100644 index 0000000000..1112aa6bca --- /dev/null +++ b/vlib/os/sleeping.c.v @@ -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 + } + } + } +} diff --git a/vlib/os/sleeping.js.v b/vlib/os/sleeping.js.v new file mode 100644 index 0000000000..6274523ba3 --- /dev/null +++ b/vlib/os/sleeping.js.v @@ -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)) {} +}