diff options
Diffstat (limited to 'v_windows/v/vlib/os/filelock/lib_nix.c.v')
-rw-r--r-- | v_windows/v/vlib/os/filelock/lib_nix.c.v | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/v_windows/v/vlib/os/filelock/lib_nix.c.v b/v_windows/v/vlib/os/filelock/lib_nix.c.v new file mode 100644 index 0000000..1af9916 --- /dev/null +++ b/v_windows/v/vlib/os/filelock/lib_nix.c.v @@ -0,0 +1,82 @@ +module filelock + +import time + +#include <sys/file.h> + +fn C.unlink(&char) int +fn C.open(&char, int, int) int +fn C.flock(int, int) int + +[unsafe] +pub fn (mut l FileLock) unlink() { + if l.fd != -1 { + C.close(l.fd) + l.fd = -1 + } + C.unlink(&char(l.name.str)) +} + +pub fn (mut l FileLock) acquire() ?bool { + if l.fd != -1 { + // lock already acquired by this instance + return false + } + fd := open_lockfile(l.name) + if fd == -1 { + return error('cannot create lock file $l.name') + } + if C.flock(fd, C.LOCK_EX) == -1 { + C.close(fd) + return error('cannot lock') + } + l.fd = fd + return true +} + +pub fn (mut l FileLock) release() bool { + if l.fd != -1 { + unsafe { + l.unlink() + } + return true + } + return false +} + +pub fn (mut l FileLock) wait_acquire(s int) ?bool { + fin := time.now().add(s) + for time.now() < fin { + if l.try_acquire() { + return true + } + C.usleep(1000) + } + return false +} + +fn open_lockfile(f string) int { + mut fd := C.open(&char(f.str), C.O_CREAT, 0o644) + if fd == -1 { + // if stat is too old delete lockfile + fd = C.open(&char(f.str), C.O_RDONLY, 0) + } + return fd +} + +pub fn (mut l FileLock) try_acquire() bool { + if l.fd != -1 { + return true + } + fd := open_lockfile('$l.name') + if fd != -1 { + err := C.flock(fd, C.LOCK_EX | C.LOCK_NB) + if err == -1 { + C.close(fd) + return false + } + l.fd = fd + return true + } + return false +} |