async node js addon calling javascript callback not working

36 views
Skip to first unread message

shah...@essential.com

unread,
May 24, 2017, 9:41:12 PM5/24/17
to libuv
Hello everyone,

I have a node js service that calls into a native C library. The native library, fire events repeatedly and continuously. These events are delivered to a C callback function. My goal is to call a Javascript callback from this native C callback.

Based on my reading, I am using  uv_async_init and uv_async_send to accomplish this goal.

The problem I am encountering is that my native C callback function gets called many times and in there uv_async_send is called many times, but the function passed to uv_async_init is called only once and only when my program exits.

Here is my C code:

=====================================================
#include "jsaudio.h"
#include <iostream>

using namespace v8;

static void recordAudioCallback(int index);
void asyncmsg(uv_async_t* handle);
Callback* cbPeriodic;
uv_async_t async;
uv_loop_t* loop;

NAN_METHOD(createEngine) {
    std::cout << "==> createEngine\n" ;
}

void createAudioRecorder(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    std::cout << "==> createAudioRecorder\n";
}

void startRecording(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    std::cout << "==> startRecording\n";
    cbPeriodic = new Callback(info[0].As<Function>());
    loop = uv_default_loop();
    uv_async_init(loop, &async, asyncmsg);
}

void asyncmsg(uv_async_t* handle) {
  std::cout << "==> asyncmsg \n";
  Nan::HandleScope scope;
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  Local<Value> argv[] = { v8::String::NewFromUtf8(isolate, "Hello world") };
  cbPeriodic->Call(1, argv);
}

/* This my callback that gets called many times, by a native library(/
static void recordAudioCallback(int index) {
  std::cout << "==> recordAudioCallback " << index << "\n";
  uv_async_send(&async);
}
======================================================

Here is my test node.js code that calls the above native code

const jsAudio = new JsAudio({sampleRate: 48000, bufferSize: 8192})

function Test () {
  jsAudio.createEngine();

  jsAudio.createAudioRecorder();

  jsAudio.startRecording(function(error, result) {
    if (error) {
      console.log('startRecording failed: ' + error);
    } else {
      console.log('startRecording result: ' + result);
    }
  });
}

Test();

var waitTill = new Date(new Date().getTime() + 3 * 1000);
while(waitTill > new Date()){}

jsAudio.shutdown();

console.log('program exit...');

==========================================================


Here is the out:


==> createEngine
==> createAudioRecorder
==> startRecording
==> recordAudioCallback 0
==> recordAudioCallback 1
==> recordAudioCallback 0
==> recordAudioCallback 1
==> recordAudioCallback 0
==> shutdown
program exit...
==> asyncmsg 
startRecording failed: Hello world

===========================================================

Why asyncmsg is called only once! even though recordAudioCallback is called several times! Any why is it called after program exits!

Any help is appreciated.

Regards, Shahriar

Trevor Blackwell

unread,
Aug 2, 2017, 2:32:36 AM8/2/17
to libuv

You're busy-waiting in Javascript:

> while(waitTill > new Date()){}


which doesn't allow anything else to run. Do something like this instead:

setTimeout(function() {
  jsAudio
.shutdown();
}, 3000);

Reply all
Reply to author
Forward
0 new messages