I tried with uv_queue_work() first. But it didn't seem to match what I needed or maybe I didn't use it correctly (?). What I did: - uv_queue_work(... work_cb, workAfter_cb) - in work_cb() I would call my driver method call_driver(..., driver_cb, baton);
But this wasn't ideal because I would have to block work_cb() until driver_cb() would be called back from the driver. Also, I wasn't quite sure that in driver_cb, I would unlock the right work_cb() method. As far as I understand uv.h, with uv_async_init(), I'm just declaring what to do when uv_async_send() is called. And, since I have a handle, I'm 'sure' I launch the corresponding workAfter() to my driver_cb(). I forgot to mention that there might be many calls to the driver (and it's a hardware driver in its own thread...), which in turns would call the same driver_cb() so it was necessary to map some baton to the JS method. I tried on Mac and Linux and got the same async behavior and the right JS methods being called back with correct timing ;-) ;-) You are right that the hardware task may be long-lived and indeed the driver calls back to report progress or error. So it's pretty similar to having a long-lived CPU thread. However, if I was using a CPU thread, I think uv_queue_work would have been more appropriate. But here, the hardware has its own thread management so it's more like a case of sync'ing between 2 independent thread pools. On Sunday, March 18, 2012 12:56:10 PM UTC-7, Nathan Rajlich wrote: > > You're correct in that uv_queue_work() is the replacement for > eio_custom(), so that is ideal for situations where you need to do some > long (possibly CPU-bound) task on libuv's thread pool, then firing a single > callback on the main thread when that is done. > > I may be incorrect, but I was under the impression that @m1k3l was doing > something on another thread that is possibly long-lived, or doesn't > necessarily finish doing its business before needing to communicate back to > the main thread. I think a good use-case for this could be reporting > progress events back to the main thread from a thread doing a lot of work > that may take a long time. > > Of course, someone correct me if I have a misunderstanding here :) > > On Sun, Mar 18, 2012 at 8:50 AM, Micheil Smith <[email protected]>wrote: > >> @Nathan, you probably know this stuff better than me now days, but >> couldn't @m1k3l just use uv_queue_work() to enqueue the call to a >> third-party library? >> >> (mainly due to the fact that uv_queue_work appears to be similar to >> eio_custom.) >> >> – Micheil >> >> On 16/03/2012, at 9:56 PM, m1k3l wrote: >> >> > Thanks! I got it to work. Here is what I did, let me know if this >> correct. >> > >> > struct Baton { >> > Persistent<Function> callback; >> > int error; >> > std::string error_message; >> > uv_async_t async; >> > >> > // Custom data >> > Persistent<Object> data; >> > }; >> > >> > JS_METHOD(Event::setCallback) { >> > Baton *baton=new Baton(); >> > >> baton->callback=Persistent<Function>::New(Local<Function>::Cast(args[0])); >> > >> > uv_async_init(uv_default_loop(), &baton->async, After_cb); // tell UV >> to call After_cb() async >> > >> > baton->async.data=baton; >> > >> > call_driver(..., driver_cb, baton); >> > } >> > >> > >> > void driver_cb (int status, void *user_data) >> > { >> > ... >> > uv_async_send(((Baton*) user_data)->async); // wakes up UV to call >> After_cb() >> > } >> > >> > void After_cb(uv_async_t *handle, int status) { >> > Baton *baton = static_cast<Baton*>(handle->data); >> > uv_close((uv_handle_t*) &baton->async,NULL); // necessary otherwise UV >> will block >> > ... >> > baton->callback->Call(v8::Context::GetCurrent()->Global(), 1, argv); >> // call the JS callback method as usual >> > ... >> > baton->callback.Dispose(); // delete the baton >> > baton->data.Dispose(); >> > delete baton; >> > } >> > >> > >> > >> > On Friday, March 16, 2012 10:48:42 AM UTC-7, Nathan Rajlich wrote: >> > I'm pretty sure this is what uv_async_t, uv_async_send and friends are >> for, but somebody correct be if I am wrong. >> > >> > On Fri, Mar 16, 2012 at 10:22 AM, m1k3l <[email protected]> wrote: >> > Hi, >> > >> > I have a native method running in its own thread and calling a callback >> to post its status. The callback has some user data that I'd like to post >> to JS. >> > Since the callback is running in a different thread than v8, I can't >> use any v8 method to call a JS callback function. So I wonder if there is a >> way to use some persistent objects to do that? >> > >> > One solution I found is to use queue the native method using libuv. >> This way, I can use a busy wait in uv's Work callback method until my >> native method's callback is called. Then uv's Work callback proceed and I >> can use uv's After callback to call the JS callback method, as usual. >> > >> > While this seems to work, it still looks like very hack-ish. Is there a >> better solution/pattern? >> > >> > Thanks >> > >> > >> > On Friday, March 16, 2012 10:48:42 AM UTC-7, Nathan Rajlich wrote: >> > I'm pretty sure this is what uv_async_t, uv_async_send and friends are >> for, but somebody correct be if I am wrong. >> > >> > On Fri, Mar 16, 2012 at 10:22 AM, m1k3l <[email protected]> wrote: >> > Hi, >> > >> > I have a native method running in its own thread and calling a callback >> to post its status. The callback has some user data that I'd like to post >> to JS. >> > Since the callback is running in a different thread than v8, I can't >> use any v8 method to call a JS callback function. So I wonder if there is a >> way to use some persistent objects to do that? >> > >> > One solution I found is to use queue the native method using libuv. >> This way, I can use a busy wait in uv's Work callback method until my >> native method's callback is called. Then uv's Work callback proceed and I >> can use uv's After callback to call the JS callback method, as usual. >> > >> > While this seems to work, it still looks like very hack-ish. Is there a >> better solution/pattern? >> > >> > Thanks >> > >> >> >
