Skip to content

Commit

Permalink
SQLITE_FCNTL_BUSYHANDLER.
Browse files Browse the repository at this point in the history
  • Loading branch information
ncruces committed Jan 14, 2025
1 parent 8887036 commit 3bae1d7
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 4 deletions.
1 change: 1 addition & 0 deletions embed/exports.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_hard_heap_limit64
sqlite3_interrupt
sqlite3_invoke_busy_handler_go
sqlite3_last_insert_rowid
sqlite3_limit
sqlite3_malloc64
Expand Down
5 changes: 5 additions & 0 deletions sqlite3/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,10 @@ int sqlite3_os_init() {
return SQLITE_OK;
}

int sqlite3_invoke_busy_handler_go(sqlite3_int64 token) {
void **ap = (void **)&token;
return ((int(*)(void *))(ap[0]))(ap[1]);
}

static_assert(offsetof(sqlite3_vfs, zName) == 16, "Unexpected offset");
static_assert(offsetof(struct go_file, handle) == 4, "Unexpected offset");
19 changes: 17 additions & 2 deletions util/vfsutil/wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func WrapPersistWAL(f vfs.File) bool {
return false
}

// WrapSetPersistentWAL helps wrap [vfs.FilePersistWAL].
func WrapSetPersistentWAL(f vfs.File, keepWAL bool) {
// WrapSetPersistWAL helps wrap [vfs.FilePersistWAL].
func WrapSetPersistWAL(f vfs.File, keepWAL bool) {
if f, ok := f.(vfs.FilePersistWAL); ok {
f.SetPersistWAL(keepWAL)
}
Expand Down Expand Up @@ -99,6 +99,14 @@ func WrapOverwrite(f vfs.File) error {
return sqlite3.NOTFOUND
}

// WrapSyncSuper helps wrap [vfs.FileSync].
func WrapSyncSuper(f vfs.File, super string) error {
if f, ok := f.(vfs.FileSync); ok {
return f.SyncSuper(super)
}
return sqlite3.NOTFOUND
}

// WrapCommitPhaseTwo helps wrap [vfs.FileCommitPhaseTwo].
func WrapCommitPhaseTwo(f vfs.File) error {
if f, ok := f.(vfs.FileCommitPhaseTwo); ok {
Expand Down Expand Up @@ -153,6 +161,13 @@ func WrapPragma(f vfs.File, name, value string) (string, error) {
return "", sqlite3.NOTFOUND
}

// WrapBusyHandler helps wrap [vfs.FilePragma].
func WrapBusyHandler(f vfs.File, handler func() bool) {
if f, ok := f.(vfs.FileBusyHandler); ok {
f.BusyHandler(handler)
}
}

// WrapSharedMemory helps wrap [vfs.FileSharedMemory].
func WrapSharedMemory(f vfs.File) vfs.SharedMemory {
if f, ok := f.(vfs.FileSharedMemory); ok {
Expand Down
10 changes: 9 additions & 1 deletion vfs/adiantum/hbsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (h *hbshFile) PersistentWAL() bool {
}

func (h *hbshFile) SetPersistentWAL(keepWAL bool) {
vfsutil.WrapSetPersistentWAL(h.File, keepWAL) // notest
vfsutil.WrapSetPersistWAL(h.File, keepWAL) // notest
}

func (h *hbshFile) HasMoved() (bool, error) {
Expand All @@ -253,6 +253,10 @@ func (h *hbshFile) Overwrite() error {
return vfsutil.WrapOverwrite(h.File) // notest
}

func (h *hbshFile) SyncSuper(super string) error {
return vfsutil.WrapSyncSuper(h.File, super) // notest
}

func (h *hbshFile) CommitPhaseTwo() error {
return vfsutil.WrapCommitPhaseTwo(h.File) // notest
}
Expand All @@ -276,3 +280,7 @@ func (h *hbshFile) CheckpointStart() {
func (h *hbshFile) CheckpointDone() {
vfsutil.WrapCheckpointDone(h.File) // notest
}

func (h *hbshFile) BusyHandler(handler func() bool) {
vfsutil.WrapBusyHandler(h.File, handler) // notest
}
9 changes: 9 additions & 0 deletions vfs/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ type FilePragma interface {
Pragma(name, value string) (string, error)
}

// FileBusyHandler extends File to implement the
// SQLITE_FCNTL_BUSYHANDLER file control opcode.
//
// https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntlbusyhandler
type FileBusyHandler interface {
File
BusyHandler(func() bool)
}

// FileSharedMemory extends File to possibly implement
// shared-memory for the WAL-index.
// The same shared-memory instance must be returned
Expand Down
14 changes: 14 additions & 0 deletions vfs/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,20 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
return ret
}

case _FCNTL_BUSYHANDLER:
if file, ok := file.(FileBusyHandler); ok {
arg := util.ReadUint64(mod, pArg)
fn := mod.ExportedFunction("sqlite3_invoke_busy_handler_go")
file.BusyHandler(func() bool {
stack := [...]uint64{arg}
if err := fn.CallWithStack(ctx, stack[:]); err != nil {
panic(err)
}
return uint32(stack[0]) != 0
})
return _OK
}

case _FCNTL_LOCK_TIMEOUT:
if file, ok := file.(FileSharedMemory); ok {
if shm, ok := file.SharedMemory().(blockingSharedMemory); ok {
Expand Down
10 changes: 9 additions & 1 deletion vfs/xts/xts.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (x *xtsFile) PersistentWAL() bool {
}

func (x *xtsFile) SetPersistentWAL(keepWAL bool) {
vfsutil.WrapSetPersistentWAL(x.File, keepWAL) // notest
vfsutil.WrapSetPersistWAL(x.File, keepWAL) // notest
}

func (x *xtsFile) HasMoved() (bool, error) {
Expand All @@ -249,6 +249,10 @@ func (x *xtsFile) Overwrite() error {
return vfsutil.WrapOverwrite(x.File) // notest
}

func (x *xtsFile) SyncSuper(super string) error {
return vfsutil.WrapSyncSuper(x.File, super) // notest
}

func (x *xtsFile) CommitPhaseTwo() error {
return vfsutil.WrapCommitPhaseTwo(x.File) // notest
}
Expand All @@ -272,3 +276,7 @@ func (x *xtsFile) CheckpointStart() {
func (x *xtsFile) CheckpointDone() {
vfsutil.WrapCheckpointDone(x.File) // notest
}

func (x *xtsFile) BusyHandler(handler func() bool) {
vfsutil.WrapBusyHandler(x.File, handler) // notest
}

0 comments on commit 3bae1d7

Please sign in to comment.