diff options
Diffstat (limited to 'callback.go')
-rw-r--r-- | callback.go | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/callback.go b/callback.go index 6450575..c3ce752 100644 --- a/callback.go +++ b/callback.go @@ -35,56 +35,55 @@ import ( //export callbackTrampoline func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) { args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] - fi := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*functionInfo) + fi := lookupHandle(C.sqlite3_user_data(ctx)).(*functionInfo) fi.Call(ctx, args) } //export stepTrampoline func stepTrampoline(ctx *C.sqlite3_context, argc C.int, argv **C.sqlite3_value) { args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:int(argc):int(argc)] - ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo) + ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo) ai.Step(ctx, args) } //export doneTrampoline func doneTrampoline(ctx *C.sqlite3_context) { - handle := uintptr(C.sqlite3_user_data(ctx)) - ai := lookupHandle(handle).(*aggInfo) + ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo) ai.Done(ctx) } //export compareTrampoline -func compareTrampoline(handlePtr uintptr, la C.int, a *C.char, lb C.int, b *C.char) C.int { +func compareTrampoline(handlePtr unsafe.Pointer, la C.int, a *C.char, lb C.int, b *C.char) C.int { cmp := lookupHandle(handlePtr).(func(string, string) int) return C.int(cmp(C.GoStringN(a, la), C.GoStringN(b, lb))) } //export commitHookTrampoline -func commitHookTrampoline(handle uintptr) int { +func commitHookTrampoline(handle unsafe.Pointer) int { callback := lookupHandle(handle).(func() int) return callback() } //export rollbackHookTrampoline -func rollbackHookTrampoline(handle uintptr) { +func rollbackHookTrampoline(handle unsafe.Pointer) { callback := lookupHandle(handle).(func()) callback() } //export updateHookTrampoline -func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, rowid int64) { +func updateHookTrampoline(handle unsafe.Pointer, op int, db *C.char, table *C.char, rowid int64) { callback := lookupHandle(handle).(func(int, string, string, int64)) callback(op, C.GoString(db), C.GoString(table), rowid) } //export authorizerTrampoline -func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int { +func authorizerTrampoline(handle unsafe.Pointer, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int { callback := lookupHandle(handle).(func(int, string, string, string) int) return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3)) } //export preUpdateHookTrampoline -func preUpdateHookTrampoline(handle uintptr, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) { +func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) { hval := lookupHandleVal(handle) data := SQLitePreUpdateData{ Conn: hval.db, @@ -105,33 +104,27 @@ type handleVal struct { } var handleLock sync.Mutex -var handleVals = make(map[uintptr]handleVal) -var handleIndex uintptr = 100 +var handleVals = make(map[unsafe.Pointer]handleVal) -func newHandle(db *SQLiteConn, v interface{}) uintptr { +func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer { handleLock.Lock() defer handleLock.Unlock() - i := handleIndex - handleIndex++ - handleVals[i] = handleVal{db, v} - return i + val := handleVal{db: db, val: v} + var p unsafe.Pointer = C.malloc(C.size_t(1)) + if p == nil { + panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil") + } + handleVals[p] = val + return p } -func lookupHandleVal(handle uintptr) handleVal { +func lookupHandleVal(handle unsafe.Pointer) handleVal { handleLock.Lock() defer handleLock.Unlock() - r, ok := handleVals[handle] - if !ok { - if handle >= 100 && handle < handleIndex { - panic("deleted handle") - } else { - panic("invalid handle") - } - } - return r + return handleVals[handle] } -func lookupHandle(handle uintptr) interface{} { +func lookupHandle(handle unsafe.Pointer) interface{} { return lookupHandleVal(handle).val } @@ -141,6 +134,7 @@ func deleteHandles(db *SQLiteConn) { for handle, val := range handleVals { if val.db == db { delete(handleVals, handle) + C.free(handle) } } } |