@@ -7,25 +7,41 @@ package metacall
77import "C"
88
99import (
10- "errors "
10+ "fmt "
1111 "runtime"
1212 "sync"
1313 "unsafe"
1414)
1515
16- const PtrSizeInBytes = (32 << uintptr (^ uintptr (0 )>> 63 )) >> 3
16+ type loadFromFileSafeWork struct {
17+ tag string
18+ scripts []string
19+ err chan error
20+ }
21+
22+ type callReturnSafeWork struct {
23+ value interface {}
24+ err error
25+ }
1726
18- type Work interface {}
27+ type callSafeWork struct {
28+ function string
29+ size int
30+ args []interface {}
31+ ret chan callReturnSafeWork
32+ }
33+
34+ const PtrSizeInBytes = (32 << uintptr (^ uintptr (0 )>> 63 )) >> 3
1935
20- var queue = make (chan Work , 1 )
36+ var queue = make (chan interface {} , 1 )
2137var toggle chan struct {}
2238var lock sync.Mutex
2339var wg sync.WaitGroup
2440
2541func Initialize () error {
2642 // TODO: Remove this once go loader is implemented
27- if int (C .metacall_initialize ()) != 0 {
28- return errors . New ( " MetaCall failed to initialize" )
43+ if result := int (C .metacall_initialize ()); result != 0 {
44+ return fmt . Errorf ( "initializing MetaCall (error code %d)" , result )
2945 }
3046
3147 return nil
@@ -42,15 +58,19 @@ func InitializeSafe() error {
4258 }
4359
4460 toggle = make (chan struct {}, 1 )
61+ initErr := make (chan error , 1 )
4562
46- go func (<- chan struct {}) {
63+ go func (initErr chan error , toggle <- chan struct {}) {
4764 // Bind this goroutine to its thread
4865 runtime .LockOSThread ()
4966
5067 // Initialize MetaCall
51- err := Initialize ()
68+ if err := Initialize (); err != nil {
69+ initErr <- err
70+ return
71+ }
5272
53- // TODO: Here I must pass err to the outside function
73+ close ( initErr )
5474
5575 for {
5676 select {
@@ -64,9 +84,9 @@ func InitializeSafe() error {
6484 wg .Done ()
6585 }
6686 }
67- }(toggle )
87+ }(initErr , toggle )
6888
69- return nil // TODO: return err
89+ return <- initErr
7090}
7191
7292func LoadFromFile (tag string , scripts []string ) error {
@@ -86,16 +106,23 @@ func LoadFromFile(tag string, scripts []string) error {
86106 }
87107
88108 if int (C .metacall_load_from_file (cTag , (* * C .char )(cScripts ), (C .size_t )(size ), nil )) != 0 {
89- return errors . New ( "MetaCall failed to load script" )
109+ return fmt . Errorf ( "%s loader failed to load a script from the list: %v" , tag , scripts )
90110 }
91111
92112 return nil
93113}
94114
95115func LoadFromFileSafe (tag string , scripts []string ) error {
96- w := Work {}
116+ result := make (chan error , 1 )
117+ w := loadFromFileSafeWork {
118+ tag ,
119+ scripts ,
120+ result ,
121+ }
97122 wg .Add (1 )
98123 queue <- w
124+
125+ return <- result
99126}
100127
101128func Call (function string , args ... interface {}) (interface {}, error ) {
@@ -106,7 +133,7 @@ func Call(function string, args ...interface{}) (interface{}, error) {
106133 cFunc := C .metacall_function (cFunction )
107134
108135 if cFunc == nil {
109- return nil , errors . New ( "Function not found" )
136+ return nil , fmt . Errorf ( "function %s not found", function )
110137 }
111138
112139 size := len (args )
@@ -184,17 +211,25 @@ func Call(function string, args ...interface{}) (interface{}, error) {
184211
185212// Call sends work and blocks until it's processed
186213func CallSafe (function string , args ... interface {}) (interface {}, error ) {
187- w := Work {}
214+ ret := make (chan callReturnSafeWork , 1 )
215+ w := callSafeWork {
216+ function : function ,
217+ size : len (args ),
218+ args : args ,
219+ ret : ret ,
220+ }
188221 wg .Add (1 )
189222 queue <- w
223+
224+ return nil , nil // TODO
190225}
191226
192227func Destroy () {
193228 C .metacall_destroy ()
194229}
195230
196231// Shutdown disables the metacall adapter waiting for all calls to complete
197- func DestorySafe () {
232+ func DestroySafe () {
198233 lock .Lock ()
199234 close (toggle )
200235 toggle = nil
@@ -203,33 +238,3 @@ func DestorySafe() {
203238 // Wait for all work to complete
204239 wg .Wait ()
205240}
206-
207- /*
208- func main() {
209-
210- if err := metacall.Initialize(); err != nil {
211- fmt.Println(err)
212- os.Exit(1)
213- }
214-
215- defer metacall.Destroy()
216-
217- scripts := []string{ "test.mock" }
218-
219- if err := metacall.LoadFromFile("mock", scripts); err != nil {
220- fmt.Println(err)
221- return
222- }
223-
224- ret, err := metacall.Call("three_str", "e", "f", "g")
225-
226- if err != nil {
227- fmt.Println(err)
228- return
229- }
230-
231- if str, ok := ret.(string); ok {
232- fmt.Println(str)
233- }
234- }
235- */
0 commit comments