Using the V8 locking API

0 views
Skip to first unread message

Miikka Miettinen

unread,
Dec 23, 2013, 10:34:39 AM12/23/13
to node-...@googlegroups.com
Hi,

I'm experimenting with a node-webkit app that would display data coming from a kind of sensor. A native module receives the data through callbacks, and I'd like to forward the data to the node-webkit app. The callbacks happen in a different thread, however, and I should therefore hold a lock on the V8 isolate during the execution of the callback.

If I include the use of a Locker to the "hello world" Node addon example [1], it works when compiled with node-gyp and run from the command line, but fails with nw-gyp and node-webkit. The error message is "Entering the V8 API without proper locking in place". I wonder if accessing an isolate from multiple threads is something that can be done in node-webkit?

Thanks,
Miikka

[1] https://github.com/rvagg/node-addon-examples/tree/master/1_hello_world

----------

#include <node.h>
#include <v8.h>

using namespace v8;

Handle<Value> Method(const Arguments& args) {
Isolate* isolate = Isolate::GetCurrent(); //<--- added this
Locker locker(isolate); //<--- ...and this
HandleScope scope;
return scope.Close(String::New("world"));
}

void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("hello"),
FunctionTemplate::New(Method)->GetFunction());
}

NODE_MODULE(hello, init)

Roger

unread,
Dec 23, 2013, 8:20:22 PM12/23/13
to Miikka Miettinen, node-...@googlegroups.com
Miikka Miettinen <miikka.m...@gmail.com> writes:

> Hi,
>
> I'm experimenting with a node-webkit app that would display data
> coming from a kind of sensor. A native module receives the data
> through callbacks, and I'd like to forward the data to the node-webkit
> app. The callbacks happen in a different thread, however, and I should
> therefore hold a lock on the V8 isolate during the execution of the
> callback.
>
> If I include the use of a Locker to the "hello world" Node addon
> example [1], it works when compiled with node-gyp and run from the
> command line, but fails with nw-gyp and node-webkit. The error message
> is "Entering the V8 API without proper locking in place". I wonder if
> accessing an isolate from multiple threads is something that can be
> done in node-webkit?

Hello, V8 doesn't support accessing a single isolate from multiple
threads. You are seeing the error message in node-webkit because it uses
a newer version of V8 (than Node v0.10), which is more developer
friendly regarding this warning -- it reports that the lock has been
held by another thread.

https://github.com/rogerwang/v8/blob/nwebkit/src/api.cc#L121

I suggest to post your events from the callback thread to the main
thread, or you can see how other modules are dealing with threads.

--
Roger

Miikka Miettinen

unread,
Dec 24, 2013, 3:43:31 AM12/24/13
to node-...@googlegroups.com
Ok, it seems that there are serious gaps in my understanding. Thanks!

--Miikka

Miikka Miettinen

unread,
Dec 26, 2013, 7:59:26 AM12/26/13
to node-...@googlegroups.com
Hello,

I'm stuck with the following error:
[700:1226/144831:FATAL:render_process_host_impl.cc(420)] Check failed: !g_exited_main_message_loop.

It's more than possible that I'm doing something wrong, but is this the kind of error that I might be able to fix on my own? I'm depending on a library (windows dll) that I can't recompile.

Thanks,
Miikka


On Dec 24, 2013, at 3:20 AM, Roger <wen...@gmail.com> wrote:

Miikka Miettinen

unread,
Dec 26, 2013, 10:29:57 AM12/26/13
to node-...@googlegroups.com
To elaborate a little bit, here's a slightly simplified version of the piece of code that I'm struggling with. It works if I hook it up with a button, but not if the call originates from the real sensor.

void DataReceiver::receiveData(const Data& data) {
std::cout << "Getting called..." << std::endl; //this gets printed out

HandleScope scope; //here it crashes because of !g_exited_main_message_loop

//forward the data to a JavaScript function:
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(Number::New(data->getValue())) };
dataConsumer->Call(Context::GetCurrent()->Global(), argc, argv);

scope.Close(Undefined());
}


I'd be very grateful for any help with this.

Thanks,
Miikka

Roger

unread,
Dec 26, 2013, 9:33:37 PM12/26/13
to Miikka Miettinen, node-...@googlegroups.com
Miikka Miettinen <miikka.m...@gmail.com> writes:

> To elaborate a little bit, here's a slightly simplified version of the
> piece of code that I'm struggling with. It works if I hook it up with
> a button, but not if the call originates from the real sensor.

Are you sure you're in a V8 Context when the control flow reaches your
function? When you call most V8 API you should be in a Context.

>
> void DataReceiver::receiveData(const Data& data) {
> std::cout << "Getting called..." << std::endl; //this gets printed out
>
> HandleScope scope; //here it crashes because of
> !g_exited_main_message_loop

btw, the error msg of 'g_exited_main_message_loop' is from the browser
process when it found the renderer process is lost. All your code, Node
and Blink runs in the renderer process. So the msg is not directly
related with your issue.

--
Roger
Reply all
Reply to author
Forward
0 new messages