v2 / vlib / os / filelock / lib.v
74 lines · 65 sloc · 1.4 KB · 3914749f5694a7f1f938d07e303a8be61e227e94
Raw
1module filelock
2
3import time
4
5// LockMode describes whether an existing file lock is shared/read or exclusive/write.
6pub enum LockMode {
7 shared
8 exclusive
9}
10
11// LockOptions configures how `new_file` locks an existing file.
12@[params]
13pub struct LockOptions {
14pub:
15 mode LockMode = .exclusive
16 start u64
17 len u64
18}
19
20enum LockTarget {
21 sidecar
22 file
23}
24
25pub struct FileLock {
26 name string
27 mode LockMode = .exclusive
28 start u64
29 len u64
30 target LockTarget = .sidecar
31mut:
32 fd i64
33}
34
35// new creates a sidecar lock file that is removed again when the lock is released.
36pub fn new(file_name string) FileLock {
37 return FileLock{
38 name: file_name
39 fd: -1
40 }
41}
42
43// new_file creates a lock for an existing file path using OS-level file locking.
44pub fn new_file(path string, options LockOptions) FileLock {
45 return FileLock{
46 name: path
47 mode: options.mode
48 start: options.start
49 len: options.len
50 target: .file
51 fd: -1
52 }
53}
54
55// wait_acquire keeps trying to acquire the lock until `timeout` expires.
56pub fn (mut l FileLock) wait_acquire(timeout time.Duration) bool {
57 fin := time.now().add(timeout)
58 for time.now() < fin {
59 if l.try_acquire() {
60 return true
61 }
62 time.sleep(1 * time.millisecond)
63 }
64 return false
65}
66
67// release unlocks the file and closes the underlying file descriptor or handle.
68pub fn (mut l FileLock) release() bool {
69 if l.fd != -1 {
70 l.close_lock()
71 return true
72 }
73 return false
74}
75