@@ -8,11 +8,20 @@ import "C"
88
99import (
1010 "errors"
11+ "runtime"
12+ "sync"
1113 "unsafe"
1214)
1315
1416const PtrSizeInBytes = (32 << uintptr (^ uintptr (0 )>> 63 )) >> 3
1517
18+ type Work interface {}
19+
20+ var queue = make (chan Work , 1 )
21+ var toggle chan struct {}
22+ var lock sync.Mutex
23+ var wg sync.WaitGroup
24+
1625func Initialize () error {
1726 // TODO: Remove this once go loader is implemented
1827 if int (C .metacall_initialize ()) != 0 {
@@ -22,8 +31,42 @@ func Initialize() error {
2231 return nil
2332}
2433
34+ // Start starts the metacall adapter
2535func InitializeSafe () error {
26- // TODO
36+ lock .Lock ()
37+ defer lock .Unlock ()
38+
39+ if toggle != nil {
40+ // Already running
41+ return nil
42+ }
43+
44+ toggle = make (chan struct {}, 1 )
45+
46+ go func (<- chan struct {}) {
47+ // Bind this goroutine to its thread
48+ runtime .LockOSThread ()
49+
50+ // Initialize MetaCall
51+ err := Initialize ()
52+
53+ // TODO: Here I must pass err to the outside function
54+
55+ for {
56+ select {
57+ case <- toggle :
58+ // Shutdown
59+ Destroy ()
60+ return
61+ case w := <- queue :
62+ // Send work
63+ fmt .Printf ("DEBUG: send work: %#v\n " , w )
64+ wg .Done ()
65+ }
66+ }
67+ }(toggle )
68+
69+ return nil // TODO: return err
2770}
2871
2972func LoadFromFile (tag string , scripts []string ) error {
@@ -49,6 +92,12 @@ func LoadFromFile(tag string, scripts []string) error {
4992 return nil
5093}
5194
95+ func LoadFromFileSafe (tag string , scripts []string ) error {
96+ w := Work {}
97+ wg .Add (1 )
98+ queue <- w
99+ }
100+
52101func Call (function string , args ... interface {}) (interface {}, error ) {
53102
54103 cFunction := C .CString (function )
@@ -133,10 +182,28 @@ func Call(function string, args ...interface{}) (interface{}, error) {
133182 return nil , nil
134183}
135184
185+ // Call sends work and blocks until it's processed
186+ func CallSafe (function string , args ... interface {}) (interface {}, error ) {
187+ w := Work {}
188+ wg .Add (1 )
189+ queue <- w
190+ }
191+
136192func Destroy () {
137193 C .metacall_destroy ()
138194}
139195
196+ // Shutdown disables the metacall adapter waiting for all calls to complete
197+ func DestorySafe () {
198+ lock .Lock ()
199+ close (toggle )
200+ toggle = nil
201+ lock .Unlock ()
202+
203+ // Wait for all work to complete
204+ wg .Wait ()
205+ }
206+
140207/*
141208func main() {
142209
0 commit comments