1//go:build ((freebsd || openbsd || netbsd || dragonfly || illumos) && (386 || arm || amd64 || arm64 || riscv64 || ppc64le)) || sqlite3_flock || sqlite3_dotlk
2
3package vfs
4
5import "github.com/ncruces/go-sqlite3/internal/util"
6
7// +checklocks:s.Mutex
8func (s *vfsShm) shmMemLock(offset, n int32, flags _ShmFlag) _ErrorCode {
9 switch {
10 case flags&_SHM_UNLOCK != 0:
11 for i := offset; i < offset+n; i++ {
12 if s.lock[i] {
13 if s.vfsShmParent.lock[i] <= 0 {
14 s.vfsShmParent.lock[i] = 0
15 } else {
16 s.vfsShmParent.lock[i]--
17 }
18 s.lock[i] = false
19 }
20 }
21 case flags&_SHM_SHARED != 0:
22 for i := offset; i < offset+n; i++ {
23 if !s.lock[i] &&
24 s.vfsShmParent.lock[i]+1 <= 0 {
25 return _BUSY
26 }
27 }
28 for i := offset; i < offset+n; i++ {
29 if !s.lock[i] {
30 s.vfsShmParent.lock[i]++
31 s.lock[i] = true
32 }
33 }
34 case flags&_SHM_EXCLUSIVE != 0:
35 for i := offset; i < offset+n; i++ {
36 if s.lock[i] {
37 // SQLite never requests an exclusive lock that it already holds.
38 panic(util.AssertErr())
39 }
40 if s.vfsShmParent.lock[i] != 0 {
41 return _BUSY
42 }
43 }
44 for i := offset; i < offset+n; i++ {
45 s.vfsShmParent.lock[i] = -1
46 s.lock[i] = true
47 }
48 default:
49 panic(util.AssertErr())
50 }
51
52 return _OK
53}