Próbuję wywołać zarejestrowaną funkcję JS, gdy wywoływany jest wywołanie zwrotne C++, ale otrzymuję błąd segfault, co do którego zakładam, że jest problemem z zakresu.Wywołanie funkcji JavaScript z wywołania zwrotnego C++ w V8
Handle<Value> addEventListener(const Arguments& args) {
HandleScope scope;
if (!args[0]->IsFunction()) {
return ThrowException(Exception::TypeError(String::New("Wrong arguments")));
}
Persistent<Function> fn = Persistent<Function>::New(Handle<Function>::Cast(args[0]));
Local<Number> num = Number::New(registerListener(&callback, &fn));
scope.Close(num);
}
Po wystąpieniu zdarzenia wywoływana jest następująca metoda. Zakładam, że prawdopodobnie dzieje się to w innym wątku, do którego V8 wykonuje JS.
void callback(int event, void* context) {
HandleScope scope;
Local<Value> args[] = { Local<Value>::New(Number::New(event)) };
Persistent<Function> *func = static_cast<Persistent<Function> *>(context);
(* func)->Call((* func), 1, args);
scope.Close(Undefined());
}
Powoduje to winy segmentacji: 11. Zauważ, że jeśli wywołanie funkcji oddzwaniania bezpośrednio z odniesieniem do Persistent od addEventListener(), to wykonuje funkcję prawidłowo.
Zakładam, że potrzebuję szafki lub izolatki? Wygląda też na to, że uv_queue_work() libuv może to rozwiązać, ale ponieważ nie zaczynam wątku, nie widzę, jak byś go użył.
Dzięki temu upraszcza to kod i rozwiązuje problem z zakresu, ale miałem nadzieję na pewne informacje jako jak oddzwonić do głównego wątku z wątku wywołania zwrotnego. Osiągnąłem to za pomocą funkcji eio_nop() z biblioteki EIO, ale preferowanym sposobem jest użycie libuv. Mój problem polega na tym, że nie wydaje się, aby libuv był równy eio_nop. – marchaos
@marchaos Ok. Nie do końca wiedziałem, o co prosisz po stronie wątków. Jak rozumiem, to, czego szukasz, jest w stanie wykonać JS z wywołania zwrotnego w kontekście wątku głównego v8. Przygotowałem małą wersję tego, jak to zrobić z izolatami/szafkami (https://gist.github.com/4341994). Zauważ, że to oznacza, że musisz dostosować wszędzie, gdzie używasz V8, aby zablokować izolat zanim zrobisz cokolwiek innego! – je4d
Dzięki. Zrobi to, ale wygląda na właściwe podejście. – marchaos