1//go:build (linux || darwin) && !(sqlite3_flock || sqlite3_dotlk)
2
3package vfs
4
5import (
6 "os"
7 "time"
8
9 "golang.org/x/sys/unix"
10)
11
12func osGetSharedLock(file *os.File) _ErrorCode {
13 // Test the PENDING lock before acquiring a new SHARED lock.
14 if lock, _ := osTestLock(file, _PENDING_BYTE, 1); lock == unix.F_WRLCK {
15 return _BUSY
16 }
17 // Acquire the SHARED lock.
18 return osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)
19}
20
21func osGetReservedLock(file *os.File) _ErrorCode {
22 // Acquire the RESERVED lock.
23 return osWriteLock(file, _RESERVED_BYTE, 1, 0)
24}
25
26func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
27 if *state == LOCK_RESERVED {
28 // A PENDING lock is needed before acquiring an EXCLUSIVE lock.
29 if rc := osWriteLock(file, _PENDING_BYTE, 1, -1); rc != _OK {
30 return rc
31 }
32 *state = LOCK_PENDING
33 }
34 // Acquire the EXCLUSIVE lock.
35 return osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, time.Millisecond)
36}
37
38func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
39 if state >= LOCK_EXCLUSIVE {
40 // Downgrade to a SHARED lock.
41 if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
42 // notest // this should never happen
43 return _IOERR_RDLOCK
44 }
45 }
46 // Release the PENDING and RESERVED locks.
47 return osUnlock(file, _PENDING_BYTE, 2)
48}
49
50func osReleaseLock(file *os.File, _ LockLevel) _ErrorCode {
51 // Release all locks.
52 return osUnlock(file, 0, 0)
53}
54
55func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
56 // Test the RESERVED lock.
57 lock, rc := osTestLock(file, _RESERVED_BYTE, 1)
58 return lock == unix.F_WRLCK, rc
59}