Ich versuche, eine registrierte JS-Funktion aufzurufen, wenn ein C++ - Callback aufgerufen wird, aber ich bekomme einen segfault für das, was ich vermute, ist ein Problembereich.Aufruf der Javascript-Funktion von einem C++ - Callback in 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);
}
Wenn ein Ereignis eintritt, wird die folgende Methode aufgerufen. Ich nehme an, dass dies wahrscheinlich in einem anderen Thread geschieht, in dem V8 JS ausführt.
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());
}
Dies verursacht eine Segmentation fault: 11. Man beachte, dass, wenn ich die Callback-Funktion direkt mit einem Verweis auf Persistent von addEventListener() aufrufen, es die Funktion richtig ausgeführt wird.
Ich gehe davon aus, dass ich ein Schließfach oder Isolieren brauche? Es sieht auch so aus, als könnte libuv's uv_queue_work() das lösen, aber da ich den Thread nicht starte, kann ich nicht sehen, wie du ihn benutzen würdest.
Danke, das vereinfacht den Code und behebt das Problem mit dem Bereich, aber ich hatte auf einige Informationen gehofft wie aus dem Callback-Thread zum Haupt-Thread zurückgerufen wird. Ich habe dies mit der Funktion eio_nop() aus der EIO-Bibliothek erreicht, aber der bevorzugte Weg ist die Verwendung von libuv. Mein Problem ist, dass es kein libuv-Äquivalent von eio_nop zu geben scheint. – marchaos
@marchaos Ok. Ich war nicht ganz klar, was Sie auf der Threading-Seite wollten. Wie ich es verstehe, was Sie suchen, ist in der Lage, JS aus dem Callback im Hauptkontext des v8-Threads auszuführen. Ich habe eine kleine Demo zusammengestellt, wie man das mit Isolaten/Schließfächern macht (https://gist.github.com/4341994). Beachten Sie, dass dies bedeutet, dass Sie überall einstellen müssen, wo Sie V8 verwenden, um das Isolat zu sperren, bevor Sie etwas anderes tun! – je4d
Danke. Ich werde es versuchen, aber es sieht nach dem richtigen Ansatz aus. – marchaos