diff options
| author | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
|---|---|---|
| committer | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
| commit | f5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch) | |
| tree | 2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/vlib/os/filelock | |
| download | cli-tools-windows-master.tar.gz cli-tools-windows-master.tar.bz2 cli-tools-windows-master.zip  | |
Diffstat (limited to 'v_windows/v/vlib/os/filelock')
| -rw-r--r-- | v_windows/v/vlib/os/filelock/filelock_test.v | 27 | ||||
| -rw-r--r-- | v_windows/v/vlib/os/filelock/lib.v | 14 | ||||
| -rw-r--r-- | v_windows/v/vlib/os/filelock/lib_nix.c.v | 82 | ||||
| -rw-r--r-- | v_windows/v/vlib/os/filelock/lib_windows.c.v | 75 | 
4 files changed, 198 insertions, 0 deletions
diff --git a/v_windows/v/vlib/os/filelock/filelock_test.v b/v_windows/v/vlib/os/filelock/filelock_test.v new file mode 100644 index 0000000..658d3aa --- /dev/null +++ b/v_windows/v/vlib/os/filelock/filelock_test.v @@ -0,0 +1,27 @@ +import os +import os.filelock + +fn test_flock() { +	lockfile := 'test.lock' +	mut l := filelock.new(lockfile) +	assert !os.exists(lockfile) +	l.acquire() or { panic(err) } +	assert os.exists(lockfile) +	// do stuff +	l.release() +	assert !os.exists(lockfile) +} + +fn test_flock_try() { +	lockfile := 'test-try.lock' +	mut l := filelock.new(lockfile) +	assert l.try_acquire() +	l.release() +	assert !os.exists(lockfile) +	assert l.try_acquire() +	assert os.exists(lockfile) +	l.release() +	assert l.try_acquire() +	l.release() +	assert !os.exists(lockfile) +} diff --git a/v_windows/v/vlib/os/filelock/lib.v b/v_windows/v/vlib/os/filelock/lib.v new file mode 100644 index 0000000..5a89ad8 --- /dev/null +++ b/v_windows/v/vlib/os/filelock/lib.v @@ -0,0 +1,14 @@ +module filelock + +pub struct FileLock { +	name string +mut: +	fd int +} + +pub fn new(fileName string) FileLock { +	return FileLock{ +		name: fileName +		fd: -1 +	} +} 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 +} diff --git a/v_windows/v/vlib/os/filelock/lib_windows.c.v b/v_windows/v/vlib/os/filelock/lib_windows.c.v new file mode 100644 index 0000000..56cbace --- /dev/null +++ b/v_windows/v/vlib/os/filelock/lib_windows.c.v @@ -0,0 +1,75 @@ +module filelock + +import time + +fn C.DeleteFileW(&u16) bool +fn C.CreateFileW(&u16, u32, u32, voidptr, u32, u32, voidptr) voidptr +fn C.CloseHandle(voidptr) bool + +pub fn (mut l FileLock) unlink() { +	if l.fd != -1 { +		C.CloseHandle(l.fd) +		l.fd = -1 +	} +	t_wide := l.name.to_wide() +	C.DeleteFileW(t_wide) +} + +pub fn (mut l FileLock) acquire() ?bool { +	if l.fd != -1 { +		// lock already acquired by this instance +		return false +	} +	fd := open(l.name) +	if fd == -1 { +		return error('cannot create lock file $l.name') +	} +	l.fd = fd +	return true +} + +pub fn (mut l FileLock) release() bool { +	if l.fd != -1 { +		C.CloseHandle(l.fd) +		l.fd = -1 +		t_wide := l.name.to_wide() +		C.DeleteFileW(t_wide) +		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 +		} +		time.sleep(1 * time.millisecond) +	} +	return false +} + +fn open(f string) voidptr { +	f_wide := f.to_wide() +	// locking it +	fd := C.CreateFileW(f_wide, C.GENERIC_READ | C.GENERIC_WRITE, 0, 0, C.OPEN_ALWAYS, +		C.FILE_ATTRIBUTE_NORMAL, 0) +	if fd == C.INVALID_HANDLE_VALUE { +		fd == -1 +	} +	return fd +} + +pub fn (mut l FileLock) try_acquire() bool { +	if l.fd != -1 { +		// lock already acquired by this instance +		return false +	} +	fd := open(l.name) +	if fd == -1 { +		return false +	} +	l.fd = fd +	return true +}  | 
