mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 12:12:25 -05:00 
			
		
		
		
	[chore] Update WASM go-sqlite3 to v0.16.1 (#2976)
This includes support for journal mode set to WAL on the BSDs. Relates to: #1753, #2962
This commit is contained in:
		
					parent
					
						
							
								afcfa48a7d
							
						
					
				
			
			
				commit
				
					
						cc4f773b0e
					
				
			
		
					 46 changed files with 618 additions and 359 deletions
				
			
		
							
								
								
									
										8
									
								
								vendor/github.com/ncruces/go-sqlite3/go.work.sum
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/ncruces/go-sqlite3/go.work.sum
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +1,7 @@ | |||
| golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= | ||||
| golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||
| golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= | ||||
| golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | ||||
| golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= | ||||
| golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= | ||||
| golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= | ||||
| golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= | ||||
| golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= | ||||
| golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= | ||||
| golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | ||||
| golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= | ||||
|  |  | |||
							
								
								
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/alloc/alloc_other.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/alloc/alloc_other.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| //go:build !(unix || windows) || sqlite3_nosys | ||||
| 
 | ||||
| package alloc | ||||
| 
 | ||||
| import "github.com/tetratelabs/wazero/experimental" | ||||
| 
 | ||||
| func Virtual(cap, max uint64) experimental.LinearMemory { | ||||
| 	return Slice(cap, max) | ||||
| } | ||||
|  | @ -1,21 +1,20 @@ | |||
| //go:build !(darwin || linux) || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys | ||||
| 
 | ||||
| package util | ||||
| package alloc | ||||
| 
 | ||||
| import "github.com/tetratelabs/wazero/experimental" | ||||
| 
 | ||||
| func sliceAlloc(cap, max uint64) experimental.LinearMemory { | ||||
| 	return &sliceBuffer{make([]byte, cap), max} | ||||
| func Slice(cap, _ uint64) experimental.LinearMemory { | ||||
| 	return &sliceMemory{make([]byte, 0, cap)} | ||||
| } | ||||
| 
 | ||||
| type sliceBuffer struct { | ||||
| type sliceMemory struct { | ||||
| 	buf []byte | ||||
| 	max uint64 | ||||
| } | ||||
| 
 | ||||
| func (b *sliceBuffer) Free() {} | ||||
| func (b *sliceMemory) Free() {} | ||||
| 
 | ||||
| func (b *sliceBuffer) Reallocate(size uint64) []byte { | ||||
| func (b *sliceMemory) Reallocate(size uint64) []byte { | ||||
| 	if cap := uint64(cap(b.buf)); size > cap { | ||||
| 		b.buf = append(b.buf[:cap], make([]byte, size-cap)...) | ||||
| 	} else { | ||||
|  | @ -1,6 +1,6 @@ | |||
| //go:build unix && !sqlite3_nosys | ||||
| 
 | ||||
| package util | ||||
| package alloc | ||||
| 
 | ||||
| import ( | ||||
| 	"math" | ||||
|  | @ -9,7 +9,7 @@ import ( | |||
| 	"golang.org/x/sys/unix" | ||||
| ) | ||||
| 
 | ||||
| func virtualAlloc(cap, max uint64) experimental.LinearMemory { | ||||
| func Virtual(_, max uint64) experimental.LinearMemory { | ||||
| 	// Round up to the page size. | ||||
| 	rnd := uint64(unix.Getpagesize() - 1) | ||||
| 	max = (max + rnd) &^ rnd | ||||
|  | @ -1,6 +1,6 @@ | |||
| //go:build !sqlite3_nosys | ||||
| 
 | ||||
| package util | ||||
| package alloc | ||||
| 
 | ||||
| import ( | ||||
| 	"math" | ||||
|  | @ -11,7 +11,7 @@ import ( | |||
| 	"golang.org/x/sys/windows" | ||||
| ) | ||||
| 
 | ||||
| func virtualAlloc(cap, max uint64) experimental.LinearMemory { | ||||
| func Virtual(_, max uint64) experimental.LinearMemory { | ||||
| 	// Round up to the page size. | ||||
| 	rnd := uint64(windows.Getpagesize() - 1) | ||||
| 	max = (max + rnd) &^ rnd | ||||
|  | @ -32,7 +32,7 @@ func virtualAlloc(cap, max uint64) experimental.LinearMemory { | |||
| 	mem := virtualMemory{addr: r} | ||||
| 	// SliceHeader, although deprecated, avoids a go vet warning. | ||||
| 	sh := (*reflect.SliceHeader)(unsafe.Pointer(&mem.buf)) | ||||
| 	sh.Cap = int(max) // Not a bug. | ||||
| 	sh.Cap = int(max) | ||||
| 	sh.Data = r | ||||
| 	return &mem | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/alloc_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/alloc_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | |||
| //go:build !(unix || windows) || sqlite3_nosys | ||||
| 
 | ||||
| package util | ||||
| 
 | ||||
| import "github.com/tetratelabs/wazero/experimental" | ||||
| 
 | ||||
| func virtualAlloc(cap, max uint64) experimental.LinearMemory { | ||||
| 	return sliceAlloc(cap, max) | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/const.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/const.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| package util | ||||
| 
 | ||||
| // https://sqlite.com/matrix/rescode.html | ||||
| // https://sqlite.com/rescode.html | ||||
| const ( | ||||
| 	OK = 0 /* Successful result */ | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										5
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/mmap.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/mmap.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| //go:build (darwin || linux) && (amd64 || arm64 || riscv64) && !(sqlite3_noshm || sqlite3_nosys) | ||||
| //go:build unix && (amd64 || arm64 || riscv64) && !(sqlite3_noshm || sqlite3_nosys) | ||||
| 
 | ||||
| package util | ||||
| 
 | ||||
|  | @ -7,6 +7,7 @@ import ( | |||
| 	"os" | ||||
| 	"unsafe" | ||||
| 
 | ||||
| 	"github.com/ncruces/go-sqlite3/internal/alloc" | ||||
| 	"github.com/tetratelabs/wazero/api" | ||||
| 	"github.com/tetratelabs/wazero/experimental" | ||||
| 	"golang.org/x/sys/unix" | ||||
|  | @ -14,7 +15,7 @@ import ( | |||
| 
 | ||||
| func withAllocator(ctx context.Context) context.Context { | ||||
| 	return experimental.WithMemoryAllocator(ctx, | ||||
| 		experimental.MemoryAllocatorFunc(virtualAlloc)) | ||||
| 		experimental.MemoryAllocatorFunc(alloc.Virtual)) | ||||
| } | ||||
| 
 | ||||
| type mmapState struct { | ||||
|  |  | |||
							
								
								
									
										7
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,10 +1,11 @@ | |||
| //go:build !(darwin || linux) || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys | ||||
| //go:build !unix || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys | ||||
| 
 | ||||
| package util | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 
 | ||||
| 	"github.com/ncruces/go-sqlite3/internal/alloc" | ||||
| 	"github.com/tetratelabs/wazero/experimental" | ||||
| ) | ||||
| 
 | ||||
|  | @ -14,8 +15,8 @@ func withAllocator(ctx context.Context) context.Context { | |||
| 	return experimental.WithMemoryAllocator(ctx, | ||||
| 		experimental.MemoryAllocatorFunc(func(cap, max uint64) experimental.LinearMemory { | ||||
| 			if cap == max { | ||||
| 				return virtualAlloc(cap, max) | ||||
| 				return alloc.Virtual(cap, max) | ||||
| 			} | ||||
| 			return sliceAlloc(cap, max) | ||||
| 			return alloc.Slice(cap, max) | ||||
| 		})) | ||||
| } | ||||
|  |  | |||
							
								
								
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/stmt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/stmt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -441,12 +441,12 @@ func (s *Stmt) ColumnOriginName(col int) string { | |||
| // ColumnBool returns the value of the result column as a bool. | ||||
| // The leftmost column of the result set has the index 0. | ||||
| // SQLite does not have a separate boolean storage class. | ||||
| // Instead, boolean values are retrieved as integers, | ||||
| // Instead, boolean values are retrieved as numbers, | ||||
| // with 0 converted to false and any other value to true. | ||||
| // | ||||
| // https://sqlite.org/c3ref/column_blob.html | ||||
| func (s *Stmt) ColumnBool(col int) bool { | ||||
| 	return s.ColumnInt64(col) != 0 | ||||
| 	return s.ColumnFloat(col) != 0 | ||||
| } | ||||
| 
 | ||||
| // ColumnInt returns the value of the result column as an int. | ||||
|  |  | |||
							
								
								
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -68,12 +68,12 @@ func (v Value) NumericType() Datatype { | |||
| 
 | ||||
| // Bool returns the value as a bool. | ||||
| // SQLite does not have a separate boolean storage class. | ||||
| // Instead, boolean values are retrieved as integers, | ||||
| // Instead, boolean values are retrieved as numbers, | ||||
| // with 0 converted to false and any other value to true. | ||||
| // | ||||
| // https://sqlite.org/c3ref/value_blob.html | ||||
| func (v Value) Bool() bool { | ||||
| 	return v.Int64() != 0 | ||||
| 	return v.Float() != 0 | ||||
| } | ||||
| 
 | ||||
| // Int returns the value as an int. | ||||
|  |  | |||
							
								
								
									
										18
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -46,7 +46,7 @@ to check if your build supports file locking. | |||
| 
 | ||||
| ### Write-Ahead Logging | ||||
| 
 | ||||
| On 64-bit Linux and macOS, this module uses `mmap` to implement | ||||
| On 64-bit Unix, this module uses `mmap` to implement | ||||
| [shared-memory for the WAL-index](https://sqlite.org/wal.html#implementation_of_shared_memory_for_the_wal_index), | ||||
| like SQLite. | ||||
| 
 | ||||
|  | @ -54,6 +54,11 @@ To allow `mmap` to work, each connection needs to reserve up to 4GB of address s | |||
| To limit the address space each connection reserves, | ||||
| use [`WithMemoryLimitPages`](../tests/testcfg/testcfg.go). | ||||
| 
 | ||||
| With [BSD locks](https://man.freebsd.org/cgi/man.cgi?query=flock&sektion=2) | ||||
| a WAL database can only be accessed by a single proccess. | ||||
| Other processes that attempt to access a database locked with BSD locks, | ||||
| will fail with the `SQLITE_PROTOCOL` error code. | ||||
| 
 | ||||
| Otherwise, [WAL support is limited](https://sqlite.org/wal.html#noshm), | ||||
| and `EXCLUSIVE` locking mode must be set to create, read, and write WAL databases. | ||||
| To use `EXCLUSIVE` locking mode with the | ||||
|  | @ -79,8 +84,9 @@ The VFS can be customized with a few build tags: | |||
| - `sqlite3_noshm` disables shared memory on all platforms. | ||||
| 
 | ||||
| > [!IMPORTANT] | ||||
| > The default configuration of this package is compatible with | ||||
| > the standard [Unix and Windows SQLite VFSes](https://sqlite.org/vfs.html#multiple_vfses); | ||||
| > `sqlite3_flock` is compatible with the [`unix-flock` VFS](https://sqlite.org/compile.html#enable_locking_style). | ||||
| > If incompatible file locking is used, accessing databases concurrently with _other_ SQLite libraries | ||||
| > will eventually corrupt data. | ||||
| > The default configuration of this package is compatible with the standard | ||||
| > [Unix and Windows SQLite VFSes](https://sqlite.org/vfs.html#multiple_vfses); | ||||
| > `sqlite3_flock` builds are compatible with the | ||||
| > [`unix-flock` VFS](https://sqlite.org/compile.html#enable_locking_style). | ||||
| > If incompatible file locking is used, accessing databases concurrently with | ||||
| > _other_ SQLite libraries will eventually corrupt data. | ||||
|  |  | |||
							
								
								
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/api.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/api.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -168,8 +168,8 @@ type FileSharedMemory interface { | |||
| // SharedMemory is a shared-memory WAL-index implementation. | ||||
| // Use [NewSharedMemory] to create a shared-memory. | ||||
| type SharedMemory interface { | ||||
| 	shmMap(context.Context, api.Module, int32, int32, bool) (uint32, error) | ||||
| 	shmLock(int32, int32, _ShmFlag) error | ||||
| 	shmMap(context.Context, api.Module, int32, int32, bool) (uint32, _ErrorCode) | ||||
| 	shmLock(int32, int32, _ShmFlag) _ErrorCode | ||||
| 	shmUnmap(bool) | ||||
| 	io.Closer | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/const.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/const.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -47,6 +47,7 @@ const ( | |||
| 	_IOERR_SHMMAP            _ErrorCode = util.IOERR_SHMMAP | ||||
| 	_IOERR_SEEK              _ErrorCode = util.IOERR_SEEK | ||||
| 	_IOERR_DELETE_NOENT      _ErrorCode = util.IOERR_DELETE_NOENT | ||||
| 	_IOERR_GETTEMPPATH       _ErrorCode = util.IOERR_GETTEMPPATH | ||||
| 	_IOERR_BEGIN_ATOMIC      _ErrorCode = util.IOERR_BEGIN_ATOMIC | ||||
| 	_IOERR_COMMIT_ATOMIC     _ErrorCode = util.IOERR_COMMIT_ATOMIC | ||||
| 	_IOERR_ROLLBACK_ATOMIC   _ErrorCode = util.IOERR_ROLLBACK_ATOMIC | ||||
|  |  | |||
							
								
								
									
										3
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/file.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/file.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -95,6 +95,9 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error | |||
| 		f, err = osutil.OpenFile(name.String(), oflags, 0666) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		if name == nil { | ||||
| 			return nil, flags, _IOERR_GETTEMPPATH | ||||
| 		} | ||||
| 		if errors.Is(err, syscall.EISDIR) { | ||||
| 			return nil, flags, _CANTOPEN_ISDIR | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -56,7 +56,7 @@ func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, d | |||
| 			if timeout < time.Since(before) { | ||||
| 				break | ||||
| 			} | ||||
| 			osSleep(time.Duration(rand.Int63n(int64(time.Millisecond)))) | ||||
| 			time.Sleep(time.Duration(rand.Int63n(int64(time.Millisecond)))) | ||||
| 		} | ||||
| 	} | ||||
| 	return osLockErrorCode(err, def) | ||||
|  |  | |||
							
								
								
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sleep.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sleep.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | |||
| //go:build !windows || sqlite3_nosys | ||||
| 
 | ||||
| package vfs | ||||
| 
 | ||||
| import "time" | ||||
| 
 | ||||
| func osSleep(d time.Duration) { | ||||
| 	time.Sleep(d) | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -136,7 +136,7 @@ func osLock(file *os.File, flags, start, len uint32, timeout time.Duration, def | |||
| 			if timeout < time.Since(before) { | ||||
| 				break | ||||
| 			} | ||||
| 			osSleep(time.Duration(rand.Int63n(int64(time.Millisecond)))) | ||||
| 			time.Sleep(time.Duration(rand.Int63n(int64(time.Millisecond)))) | ||||
| 		} | ||||
| 	} | ||||
| 	return osLockErrorCode(err, def) | ||||
|  | @ -171,16 +171,3 @@ func osLockErrorCode(err error, def _ErrorCode) _ErrorCode { | |||
| 	} | ||||
| 	return def | ||||
| } | ||||
| 
 | ||||
| func osSleep(d time.Duration) { | ||||
| 	if d > 0 { | ||||
| 		period := max(1, d/(5*time.Millisecond)) | ||||
| 		if period < 16 { | ||||
| 			windows.TimeBeginPeriod(uint32(period)) | ||||
| 		} | ||||
| 		time.Sleep(d) | ||||
| 		if period < 16 { | ||||
| 			windows.TimeEndPeriod(uint32(period)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										43
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -51,12 +51,7 @@ type vfsShm struct { | |||
| 	readOnly bool | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, extend bool) (uint32, error) { | ||||
| 	// Ensure size is a multiple of the OS page size. | ||||
| 	if int(size)&(unix.Getpagesize()-1) != 0 { | ||||
| 		return 0, _IOERR_SHMMAP | ||||
| 	} | ||||
| 
 | ||||
| func (s *vfsShm) shmOpen() _ErrorCode { | ||||
| 	if s.File == nil { | ||||
| 		var flag int | ||||
| 		if s.readOnly { | ||||
|  | @ -67,28 +62,40 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext | |||
| 		f, err := os.OpenFile(s.path, | ||||
| 			flag|unix.O_CREAT|unix.O_NOFOLLOW, 0666) | ||||
| 		if err != nil { | ||||
| 			return 0, _CANTOPEN | ||||
| 			return _CANTOPEN | ||||
| 		} | ||||
| 		s.File = f | ||||
| 	} | ||||
| 
 | ||||
| 	// Dead man's switch. | ||||
| 	if lock, rc := osGetLock(s.File, _SHM_DMS, 1); rc != _OK { | ||||
| 		return 0, _IOERR_LOCK | ||||
| 		return _IOERR_LOCK | ||||
| 	} else if lock == unix.F_WRLCK { | ||||
| 		return 0, _BUSY | ||||
| 		return _BUSY | ||||
| 	} else if lock == unix.F_UNLCK { | ||||
| 		if s.readOnly { | ||||
| 			return 0, _READONLY_CANTINIT | ||||
| 			return _READONLY_CANTINIT | ||||
| 		} | ||||
| 		if rc := osWriteLock(s.File, _SHM_DMS, 1, 0); rc != _OK { | ||||
| 			return 0, rc | ||||
| 			return rc | ||||
| 		} | ||||
| 		if err := s.Truncate(0); err != nil { | ||||
| 			return 0, _IOERR_SHMOPEN | ||||
| 			return _IOERR_SHMOPEN | ||||
| 		} | ||||
| 	} | ||||
| 	if rc := osReadLock(s.File, _SHM_DMS, 1, 0); rc != _OK { | ||||
| 		return rc | ||||
| 	} | ||||
| 	return _OK | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, extend bool) (uint32, _ErrorCode) { | ||||
| 	// Ensure size is a multiple of the OS page size. | ||||
| 	if int(size)&(unix.Getpagesize()-1) != 0 { | ||||
| 		return 0, _IOERR_SHMMAP | ||||
| 	} | ||||
| 
 | ||||
| 	if rc := s.shmOpen(); rc != _OK { | ||||
| 		return 0, rc | ||||
| 	} | ||||
| 
 | ||||
|  | @ -99,7 +106,7 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext | |||
| 	} | ||||
| 	if n := (int64(id) + 1) * int64(size); n > o { | ||||
| 		if !extend { | ||||
| 			return 0, nil | ||||
| 			return 0, _OK | ||||
| 		} | ||||
| 		err := osAllocate(s.File, n) | ||||
| 		if err != nil { | ||||
|  | @ -115,13 +122,13 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext | |||
| 	} | ||||
| 	r, err := util.MapRegion(ctx, mod, s.File, int64(id)*int64(size), size, prot) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 		return 0, _IOERR_SHMMAP | ||||
| 	} | ||||
| 	s.regions = append(s.regions, r) | ||||
| 	return r.Ptr, nil | ||||
| 	return r.Ptr, _OK | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) error { | ||||
| func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode { | ||||
| 	// Argument check. | ||||
| 	if n <= 0 || offset < 0 || offset+n > _SHM_NLOCK { | ||||
| 		panic(util.AssertErr()) | ||||
|  | @ -165,9 +172,9 @@ func (s *vfsShm) shmUnmap(delete bool) { | |||
| 	s.regions = s.regions[:0] | ||||
| 
 | ||||
| 	// Close the file. | ||||
| 	defer s.Close() | ||||
| 	if delete { | ||||
| 		os.Remove(s.Name()) | ||||
| 		os.Remove(s.path) | ||||
| 	} | ||||
| 	s.Close() | ||||
| 	s.File = nil | ||||
| } | ||||
|  |  | |||
							
								
								
									
										259
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,259 @@ | |||
| //go:build (freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) && (amd64 || arm64 || riscv64) && !(sqlite3_noshm || sqlite3_nosys) | ||||
| 
 | ||||
| package vfs | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/ncruces/go-sqlite3/internal/util" | ||||
| 	"github.com/tetratelabs/wazero/api" | ||||
| 	"golang.org/x/sys/unix" | ||||
| ) | ||||
| 
 | ||||
| // SupportsSharedMemory is false on platforms that do not support shared memory. | ||||
| // To use [WAL without shared-memory], you need to set [EXCLUSIVE locking mode]. | ||||
| // | ||||
| // [WAL without shared-memory]: https://sqlite.org/wal.html#noshm | ||||
| // [EXCLUSIVE locking mode]: https://sqlite.org/pragma.html#pragma_locking_mode | ||||
| const SupportsSharedMemory = true | ||||
| 
 | ||||
| const _SHM_NLOCK = 8 | ||||
| 
 | ||||
| func (f *vfsFile) SharedMemory() SharedMemory { return f.shm } | ||||
| 
 | ||||
| // NewSharedMemory returns a shared-memory WAL-index | ||||
| // backed by a file with the given path. | ||||
| // It will return nil if shared-memory is not supported, | ||||
| // or not appropriate for the given flags. | ||||
| // Only [OPEN_MAIN_DB] databases may need a WAL-index. | ||||
| // You must ensure all concurrent accesses to a database | ||||
| // use shared-memory instances created with the same path. | ||||
| func NewSharedMemory(path string, flags OpenFlag) SharedMemory { | ||||
| 	if flags&OPEN_MAIN_DB == 0 || flags&(OPEN_DELETEONCLOSE|OPEN_MEMORY) != 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return &vfsShm{ | ||||
| 		path:     path, | ||||
| 		readOnly: flags&OPEN_READONLY != 0, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type vfsShmFile struct { | ||||
| 	*os.File | ||||
| 	info os.FileInfo | ||||
| 
 | ||||
| 	// +checklocks:vfsShmFilesMtx | ||||
| 	refs int | ||||
| 
 | ||||
| 	// +checklocks:lockMtx | ||||
| 	lock    [_SHM_NLOCK]int16 | ||||
| 	lockMtx sync.Mutex | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	// +checklocks:vfsShmFilesMtx | ||||
| 	vfsShmFiles    []*vfsShmFile | ||||
| 	vfsShmFilesMtx sync.Mutex | ||||
| ) | ||||
| 
 | ||||
| type vfsShm struct { | ||||
| 	*vfsShmFile | ||||
| 	path     string | ||||
| 	lock     [_SHM_NLOCK]bool | ||||
| 	regions  []*util.MappedRegion | ||||
| 	readOnly bool | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) Close() error { | ||||
| 	if s.vfsShmFile == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	// Unlock everything. | ||||
| 	s.shmLock(0, _SHM_NLOCK, _SHM_UNLOCK) | ||||
| 
 | ||||
| 	vfsShmFilesMtx.Lock() | ||||
| 	defer vfsShmFilesMtx.Unlock() | ||||
| 
 | ||||
| 	// Decrease reference count. | ||||
| 	if s.vfsShmFile.refs > 1 { | ||||
| 		s.vfsShmFile.refs-- | ||||
| 		s.vfsShmFile = nil | ||||
| 		return nil | ||||
| 	} | ||||
| 	for i, g := range vfsShmFiles { | ||||
| 		if g == s.vfsShmFile { | ||||
| 			vfsShmFiles[i] = nil | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	err := s.File.Close() | ||||
| 	s.vfsShmFile = nil | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmOpen() (rc _ErrorCode) { | ||||
| 	if s.vfsShmFile != nil { | ||||
| 		return _OK | ||||
| 	} | ||||
| 
 | ||||
| 	// Open file read-write, as it will be shared. | ||||
| 	f, err := os.OpenFile(s.path, | ||||
| 		unix.O_RDWR|unix.O_CREAT|unix.O_NOFOLLOW, 0666) | ||||
| 	if err != nil { | ||||
| 		return _CANTOPEN | ||||
| 	} | ||||
| 	// Close if file if it's not nil. | ||||
| 	defer func() { f.Close() }() | ||||
| 
 | ||||
| 	fi, err := f.Stat() | ||||
| 	if err != nil { | ||||
| 		return _IOERR_FSTAT | ||||
| 	} | ||||
| 
 | ||||
| 	vfsShmFilesMtx.Lock() | ||||
| 	defer vfsShmFilesMtx.Unlock() | ||||
| 
 | ||||
| 	// Find a shared file, increase the reference count. | ||||
| 	for _, g := range vfsShmFiles { | ||||
| 		if g != nil && os.SameFile(fi, g.info) { | ||||
| 			g.refs++ | ||||
| 			s.vfsShmFile = g | ||||
| 			return _OK | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Lock and truncate the file, if not readonly. | ||||
| 	if s.readOnly { | ||||
| 		rc = _READONLY_CANTINIT | ||||
| 	} else { | ||||
| 		if rc := osWriteLock(f, 0, 0, 0); rc != _OK { | ||||
| 			return rc | ||||
| 		} | ||||
| 		if err := f.Truncate(0); err != nil { | ||||
| 			return _IOERR_SHMOPEN | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Add the new shared file. | ||||
| 	s.vfsShmFile = &vfsShmFile{ | ||||
| 		File: f, | ||||
| 		info: fi, | ||||
| 		refs: 1, | ||||
| 	} | ||||
| 	f = nil | ||||
| 	add := true | ||||
| 	for i, g := range vfsShmFiles { | ||||
| 		if g == nil { | ||||
| 			vfsShmFiles[i] = s.vfsShmFile | ||||
| 			add = false | ||||
| 		} | ||||
| 	} | ||||
| 	if add { | ||||
| 		vfsShmFiles = append(vfsShmFiles, s.vfsShmFile) | ||||
| 	} | ||||
| 	return rc | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, extend bool) (uint32, _ErrorCode) { | ||||
| 	// Ensure size is a multiple of the OS page size. | ||||
| 	if int(size)&(unix.Getpagesize()-1) != 0 { | ||||
| 		return 0, _IOERR_SHMMAP | ||||
| 	} | ||||
| 
 | ||||
| 	if rc := s.shmOpen(); rc != _OK { | ||||
| 		return 0, rc | ||||
| 	} | ||||
| 
 | ||||
| 	// Check if file is big enough. | ||||
| 	o, err := s.Seek(0, io.SeekEnd) | ||||
| 	if err != nil { | ||||
| 		return 0, _IOERR_SHMSIZE | ||||
| 	} | ||||
| 	if n := (int64(id) + 1) * int64(size); n > o { | ||||
| 		if !extend { | ||||
| 			return 0, _OK | ||||
| 		} | ||||
| 		err := osAllocate(s.File, n) | ||||
| 		if err != nil { | ||||
| 			return 0, _IOERR_SHMSIZE | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var prot int | ||||
| 	if s.readOnly { | ||||
| 		prot = unix.PROT_READ | ||||
| 	} else { | ||||
| 		prot = unix.PROT_READ | unix.PROT_WRITE | ||||
| 	} | ||||
| 	r, err := util.MapRegion(ctx, mod, s.File, int64(id)*int64(size), size, prot) | ||||
| 	if err != nil { | ||||
| 		return 0, _IOERR_SHMMAP | ||||
| 	} | ||||
| 	s.regions = append(s.regions, r) | ||||
| 	return r.Ptr, _OK | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode { | ||||
| 	s.lockMtx.Lock() | ||||
| 	defer s.lockMtx.Unlock() | ||||
| 
 | ||||
| 	switch { | ||||
| 	case flags&_SHM_UNLOCK != 0: | ||||
| 		for i := offset; i < offset+n; i++ { | ||||
| 			if s.lock[i] { | ||||
| 				if s.vfsShmFile.lock[i] <= 0 { | ||||
| 					s.vfsShmFile.lock[i] = 0 | ||||
| 				} else { | ||||
| 					s.vfsShmFile.lock[i]-- | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	case flags&_SHM_SHARED != 0: | ||||
| 		for i := offset; i < offset+n; i++ { | ||||
| 			if s.vfsShmFile.lock[i] < 0 { | ||||
| 				return _BUSY | ||||
| 			} | ||||
| 		} | ||||
| 		for i := offset; i < offset+n; i++ { | ||||
| 			s.vfsShmFile.lock[i]++ | ||||
| 			s.lock[i] = true | ||||
| 		} | ||||
| 	case flags&_SHM_EXCLUSIVE != 0: | ||||
| 		for i := offset; i < offset+n; i++ { | ||||
| 			if s.vfsShmFile.lock[i] != 0 { | ||||
| 				return _BUSY | ||||
| 			} | ||||
| 		} | ||||
| 		for i := offset; i < offset+n; i++ { | ||||
| 			s.vfsShmFile.lock[i] = -1 | ||||
| 			s.lock[i] = true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return _OK | ||||
| } | ||||
| 
 | ||||
| func (s *vfsShm) shmUnmap(delete bool) { | ||||
| 	if s.vfsShmFile == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Unmap regions. | ||||
| 	for _, r := range s.regions { | ||||
| 		r.Unmap() | ||||
| 	} | ||||
| 	clear(s.regions) | ||||
| 	s.regions = s.regions[:0] | ||||
| 
 | ||||
| 	// Close the file. | ||||
| 	if delete { | ||||
| 		os.Remove(s.path) | ||||
| 	} | ||||
| 	s.Close() | ||||
| 	s.vfsShmFile = nil | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/shm_other.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| //go:build !(darwin || linux) || !(amd64 || arm64 || riscv64) || sqlite3_flock || sqlite3_noshm || sqlite3_nosys | ||||
| //go:build !(darwin || linux || freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys | ||||
| 
 | ||||
| package vfs | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -83,7 +83,7 @@ func vfsRandomness(ctx context.Context, mod api.Module, pVfs uint32, nByte int32 | |||
| } | ||||
| 
 | ||||
| func vfsSleep(ctx context.Context, mod api.Module, pVfs uint32, nMicro int32) _ErrorCode { | ||||
| 	osSleep(time.Duration(nMicro) * time.Microsecond) | ||||
| 	time.Sleep(time.Duration(nMicro) * time.Microsecond) | ||||
| 	return _OK | ||||
| } | ||||
| 
 | ||||
|  | @ -397,18 +397,14 @@ func vfsShmBarrier(ctx context.Context, mod api.Module, pFile uint32) { | |||
| 
 | ||||
| func vfsShmMap(ctx context.Context, mod api.Module, pFile uint32, iRegion, szRegion int32, bExtend, pp uint32) _ErrorCode { | ||||
| 	shm := vfsFileGet(ctx, mod, pFile).(FileSharedMemory).SharedMemory() | ||||
| 	p, err := shm.shmMap(ctx, mod, iRegion, szRegion, bExtend != 0) | ||||
| 	if err != nil { | ||||
| 		return vfsErrorCode(err, _IOERR_SHMMAP) | ||||
| 	} | ||||
| 	p, rc := shm.shmMap(ctx, mod, iRegion, szRegion, bExtend != 0) | ||||
| 	util.WriteUint32(mod, pp, p) | ||||
| 	return _OK | ||||
| 	return rc | ||||
| } | ||||
| 
 | ||||
| func vfsShmLock(ctx context.Context, mod api.Module, pFile uint32, offset, n int32, flags _ShmFlag) _ErrorCode { | ||||
| 	shm := vfsFileGet(ctx, mod, pFile).(FileSharedMemory).SharedMemory() | ||||
| 	err := shm.shmLock(offset, n, flags) | ||||
| 	return vfsErrorCode(err, _IOERR_SHMLOCK) | ||||
| 	return shm.shmLock(offset, n, flags) | ||||
| } | ||||
| 
 | ||||
| func vfsShmUnmap(ctx context.Context, mod api.Module, pFile, bDelete uint32) _ErrorCode { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue