From 2ca0ba2072eb3f84e68bdb3c139d54699fac7407 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. --- new/ids.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 new/ids.go diff --git a/new/ids.go b/new/ids.go new file mode 100644 index 0000000..66dd587 --- /dev/null +++ b/new/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) +}