V8: Passing an object from JavaScript to the uv_work function

OK, I have a C ++ function that I need to call from JavaScript, and one of the parameters is a JavaScript object. JavaScript looks like this:

var message = { fieldA: 42, fieldB: "moo" }; myObj.send(message, function (err) { console.log("Result: " + err); }); 

In the send () routine, I need to call my own function in another C library, which may be blocked. All functions in this library can be blocked, so I use uv_queue_work extensively.

This procedure is the first time that I got into a problem and it is related to a JavaScript object. C ++ code is as follows:

 struct SendMessageRequest { Persistent<Object> message; Persistent<Function> callback; int result; }; Handle<Value> MyObj::Send(const Arguments& args) { HandleScope scope; // Parameter checking done but not included here Local<Object> message = Local<Object>::Cast(args[0]); Local<Function> callback = Local<Function>::Cast(args[1]); // Send data to worker thread SendMessageRequest* request = new SendMessageRequest; request->message = Persistent<Object>::New(message); request->callback = Persistent<Function>::New(callback); uv_work_t* req = new uv_work_t(); req->data = request; uv_queue_work(uv_default_loop(), req, SendMessageWorker, SendMessageWorkerComplete); return scope.Close(Undefined()); } 

Everything is fine, the problem occurs when I try to receive the request-> request in the SendMessageWorker function.

 void SendMessageWorker(uv_work_t* req) { SendMessageRequest* request = (SendMessageRequest*)req->data; Local<Array> names = request->message->GetPropertyNames(); // CRASH 

It seems that calling methods from the request-> message causes an access violation at a really small address (probably a NULL pointer reference somewhere in V8 / node). Therefore, the use of request-> message directly should be incorrect. I know that to access the callback function I need to do this:

 request->callback->Call(Context::GetCurrent()->Global(), 1, argv); 

Do I need to use Context :: GetCurrent () β†’ Global () to access methods from the Object class that are wrapped by the Persistent template? If so, how to do it?

+4
source share
1 answer

The code in SendMessageWorker does not run in JavaScript - what uv_queue_work does is execute your SendMessageWorker in a separate thread, so it can also run node.js code, and when ready, SendMessageWorkerComplete is executed in the JavaScript thread.

Thus, you cannot use JavaScript variables in SendMessageWorker - if you really need to, you will have to convert them, for example. C ++ before calling uv_queue_work .

+4
source

All Articles