Skip to content

Commit

Permalink
thread safe imports and funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
drewwells committed Sep 23, 2015
1 parent 7bfc549 commit c42f6d6
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 34 deletions.
21 changes: 2 additions & 19 deletions func.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package libsass

import (
"runtime"
"unsafe"

"github.com/wellington/go-libsass/libs"
)
import "github.com/wellington/go-libsass/libs"

// HandlerFunc describes the method signature for registering
// a Go function to be called by libsass.
Expand Down Expand Up @@ -90,17 +85,5 @@ func (ctx *Context) SetFunc(goopts libs.SassOptions) {
Ctx: ctx,
}
}
// TODO: this seems to run fine with garbage collection on
// surprisingly enough
// disable garbage collection of cookies. These need to
// be manually freed in the wrapper
// runtime.SetFinalizer(&cookies, nil)
gofns := make([]libs.SassFunc, len(cookies))
runtime.SetFinalizer(&gofns, nil)
for i, cookie := range cookies {
fn := libs.SassMakeFunction(cookie.Sign,
unsafe.Pointer(&cookies[i]))
gofns[i] = fn
}
libs.BindFuncs(goopts, gofns)
libs.BindFuncs(goopts, cookies)
}
11 changes: 8 additions & 3 deletions libs/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package libs
//
import "C"
import (
"fmt"
"sync"
"unsafe"
)
Expand All @@ -29,10 +30,14 @@ var gobridgeMu sync.Mutex
//
//export GoBridge
func GoBridge(cargs UnionSassValue, ptr unsafe.Pointer) UnionSassValue {
// gobridgeMu.Lock()
// defer gobridgeMu.Unlock()
// Recover the Cookie struct passed in
ck := *(*Cookie)(ptr)
idx := (*string)(ptr)
ck, ok := globalFuncs.get(idx).(Cookie)
if !ok {
fmt.Printf("failed to resolve Cookie %p\n", ptr)
return MakeNil()
}
// ck := *(*Cookie)(ptr)

var usv UnionSassValue
err := ck.Fn(ck.Ctx, cargs, &usv)
Expand Down
18 changes: 17 additions & 1 deletion libs/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,25 @@ func SassMakeFunction(signature string, ptr unsafe.Pointer) SassFunc {
return (SassFunc)(fn)
}

var globalFuncs SafeMap

func init() {
globalFuncs.init()
}

// BindFuncs attaches a slice of Functions to a sass options. Signatures
// are already defined in the SassFunc.
func BindFuncs(opts SassOptions, funcs []SassFunc) {
func BindFuncs(opts SassOptions, cookies []Cookie) {

funcs := make([]SassFunc, len(cookies))
for i, cookie := range cookies {
idx := globalFuncs.set(cookies[i])

fn := SassMakeFunction(cookie.Sign,
unsafe.Pointer(idx))
funcs[i] = fn
}

sz := C.size_t(len(funcs))
cfuncs := C.sass_make_function_list(sz)
for i, cfn := range funcs {
Expand Down
16 changes: 8 additions & 8 deletions libs/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ import (
// delete it
type SafeMap struct {
sync.RWMutex
m map[string]interface{}
m map[*string]interface{}
}

func (s *SafeMap) init() {
s.m = make(map[string]interface{})
s.m = make(map[*string]interface{})
}

func (s *SafeMap) get(idx string) interface{} {
func (s *SafeMap) get(idx *string) interface{} {
s.RLock()
defer s.RUnlock()
return s.m[idx]
Expand All @@ -58,16 +58,16 @@ func randString(n int) string {
return string(b)
}

func (s *SafeMap) delete(idx string) {
func (s *SafeMap) delete(idx *string) {
s.Lock()
delete(s.m, idx)
s.Unlock()
}

// set accepts an entry and returns an index for it
func (s *SafeMap) set(ie interface{}) string {
idx := randString(8)

func (s *SafeMap) set(ie interface{}) *string {
i := randString(8)
idx := &i
s.Lock()
s.m[idx] = ie
defer s.Unlock()
Expand All @@ -85,7 +85,7 @@ func init() {
func BindImporter(opts SassOptions, entries []ImportEntry) {

idx := globalImports.set(entries)
ptr := unsafe.Pointer(&idx)
ptr := unsafe.Pointer(idx)

imper := C.sass_make_importer(
C.Sass_Importer_Fn(C.SassImporterHandler),
Expand Down
9 changes: 6 additions & 3 deletions libs/wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,12 @@ func GetEntry(es []ImportEntry, parent string, path string) (string, error) {
//export ImporterBridge
func ImporterBridge(url *C.char, prev *C.char, ptr unsafe.Pointer) C.Sass_Import_List {
// Retrieve the index
fmt.Printf("iBridge: % #v\n", ptr)
idx := *(*string)(ptr)
entries := globalImports.get(idx).([]ImportEntry)
idx := (*string)(ptr)
entries, ok := globalImports.get(idx).([]ImportEntry)
if !ok {
fmt.Printf("failed to resolve import slice: %p\n", ptr)
entries = []ImportEntry{}
}

parent := C.GoString(prev)
rel := C.GoString(url)
Expand Down

0 comments on commit c42f6d6

Please sign in to comment.