shm_memlk.go

 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}