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 <mich...@brandedcode.com>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 <mikese...@gmail.com> 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 <mikese...@gmail.com> 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
>> >
>>
>>
>

Reply via email to