From 64d0100d7a46ca06544b080dcee3e45d72e3df3d Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 23 Feb 2015 23:10:38 -0500 Subject: [PATCH] Started rewrite #3. The first file up for bat is an ID system for safer C/Go interop. --- ids.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 ids.go diff --git a/ids.go b/ids.go new file mode 100644 index 00000000..66dd587c --- /dev/null +++ b/ids.go @@ -0,0 +1,61 @@ +// 23 february 2015 + +package ui + +// Go pointers cannot be passed to C safely. +// The Go runtime will move them around, tripping C up. +// However, C pointers don't have this problem. +// Solution: use the C pointer to get the Go object needed! + +import ( + "fmt" + "sync" +) + +var ( + ids map[uintptr]interface{} + idsLock sync.Mutex +) + +func getGoObject(cptr uintptr) interface{} { + idsLock.Lock() + defer idsLock.Unlock() + + if i, ok := ids[cptr]; ok { + return i + } + panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p not associated with Go object in package ui", cptr)) +} + +func associateGoObject(cptr uintptr, goobj interface{}) { + idsLock.Lock() + defer idsLock.Unlock() + + if i, ok := ids[cptr]; ok { + panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p already associated with Go object of type %T but we want to associate it with Go object of type %T", cptr, i, goobj)) + } + ids[cptr] = goobj +} + +func disassociateGoObject(cptr uintptr) { + idsLock.Lock() + defer idsLock.Unlock() + + if _, ok := ids[cptr]; !ok { + panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p not associated with any Go object but we want to disassociate it", cptr)) + } + delete(ids, cptr) +} + +func idsHandler(req *request) bool { + switch req.id { + case reqObjectDestroyed: + disassociateGoObject(req.ptr) + return true + } + return false +} + +func init() { + interopHandlers = append(interopHandlers, idsHandler) +}