I am writing C++ addon using nbind - GitHub link for most thing and Nan - GitHub link for calling callbacks asynchronous. When I invoke callback only once, it works perfect. But When I invoke callback twice it gives Segmentation fault (core dumped). Couldn't find error using gdb. Here is JS and C++ codes(compiling using node-gyp configure build):
//main.js code
var nbind = require('nbind');
var lib = nbind.init().lib;
lib.HeaderExample.callJS(function(a) {
console.log("result" + a);
});
lib.HeaderExample.startThread();
lib.HeaderExample.startThread();
C++ addon's code
//c++ code
class CallbackRunner : public Nan::AsyncWorker {
public:
CallbackRunner(Nan::Callback *callback)
: AsyncWorker(callback) {}
void Execute () {}
void HandleOKCallback () {
std::cout << "running HandleOKCallback in thread " << std::this_thread::get_id() << std::endl;
Nan::HandleScope scope;
v8::Local<v8::Value> argv[] = {
Nan::New<v8::Number>(10)
};
callback->Call(1, argv);
}
};
class HeaderExample {
public:
static void callJS(nbind::cbFunction &callback) {
std::cout << "running callJS in thread " << std::this_thread::get_id() << std::endl;
m_onInitialisationStarted = new nbind::cbFunction(callback);
Nan::Callback *callbackNan = new Nan::Callback(m_onInitialisationStarted->getJsFunction());
runner = new CallbackRunner(callbackNan);
}
static void startThread() {
std::cout << "it is here";
std::thread threadS(some);
threadS.join();
}
static void some() {
std::cout << "running some in thread: " << std::this_thread::get_id() << std::endl;
if(runner){
AsyncQueueWorker(runner);
}
}
inline static nbind::cbFunction *m_onInitialisationStarted = 0;
inline static CallbackRunner *runner;
};
Your class uses
AsyncQueueWorkerto invoke theCallbackRunner, butAsyncQueueWorkercallsAsyncExecuteCompleteafter the callback is done, which in turn callsworker->Destroy(). See theAsyncQueueWorkercode fromnan.h:worker->Destroy()will delete theCallbackRunnerclass, along with theNan::Callbackthat you fed to its constructor. That is the reason why you get a segmentation fault when attempting to call this callback a second time.You might be better off basing your class on
Nan::AsyncProgressQueueWorkerinstead ofNan::AsyncWorker.AsyncProgressQueueWorkerinheritsAsyncWorkerand it allows you to schedule work from the main thread just asAsyncWorkerdoes, but it provides you with anExecutionProgressclass that allows you to use any thread to call back into the main thread any number of times while the original scheduled job is running.Nan::AsyncProgressQueueWorkerwas added to NAN in version2.8.0