app: replace C-to-Go handle maps with cgo.Handle

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-03-02 17:24:46 +01:00
parent 95365d5878
commit c0c25b777b
4 changed files with 67 additions and 63 deletions
+11 -16
View File
@@ -6,7 +6,7 @@ package app
#include <Foundation/Foundation.h>
__attribute__ ((visibility ("hidden"))) void gio_wakeupMainThread(void);
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createDisplayLink(void);
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createDisplayLink(uintptr_t handle);
__attribute__ ((visibility ("hidden"))) void gio_releaseDisplayLink(CFTypeRef dl);
__attribute__ ((visibility ("hidden"))) int gio_startDisplayLink(CFTypeRef dl);
__attribute__ ((visibility ("hidden"))) int gio_stopDisplayLink(CFTypeRef dl);
@@ -42,7 +42,7 @@ static CFTypeRef newNSString(unichar *chars, NSUInteger length) {
import "C"
import (
"errors"
"sync"
"runtime/cgo"
"sync/atomic"
"time"
"unicode/utf16"
@@ -70,9 +70,6 @@ type displayLink struct {
running uint32
}
// displayLinks maps CFTypeRefs to *displayLinks.
var displayLinks sync.Map
var mainFuncs = make(chan func(), 1)
// runOnMain runs the function on the main thread.
@@ -131,18 +128,18 @@ func NewDisplayLink(callback func()) (*displayLink, error) {
states: make(chan bool),
dids: make(chan uint64),
}
dl := C.gio_createDisplayLink()
h := cgo.NewHandle(d)
dl := C.gio_createDisplayLink(C.uintptr_t(h))
if dl == 0 {
return nil, errors.New("app: failed to create display link")
}
go d.run(dl)
go d.run(dl, h)
return d, nil
}
func (d *displayLink) run(dl C.CFTypeRef) {
func (d *displayLink) run(dl C.CFTypeRef, h cgo.Handle) {
defer C.gio_releaseDisplayLink(dl)
displayLinks.Store(dl, d)
defer displayLinks.Delete(dl)
defer h.Delete()
var stopTimer *time.Timer
var tchan <-chan time.Time
started := false
@@ -203,12 +200,10 @@ func (d *displayLink) SetDisplayID(did uint64) {
}
//export gio_onFrameCallback
func gio_onFrameCallback(dl C.CFTypeRef) {
if d, exists := displayLinks.Load(dl); exists {
d := d.(*displayLink)
if atomic.LoadUint32(&d.running) != 0 {
d.callback()
}
func gio_onFrameCallback(dl C.CFTypeRef, handle C.uintptr_t) {
d := cgo.Handle(handle).Value().(*displayLink)
if atomic.LoadUint32(&d.running) != 0 {
d.callback()
}
}