两次调用某个回调函数会导致分段错误:Nan [英] Invoking some callback function twice leads to Segmentation fault: Nan

查看:49
本文介绍了两次调用某个回调函数会导致分段错误:Nan的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写 C++ 插件,使用 nbind - GitHub 链接Nan - GitHub 链接 用于异步调用回调.当我只调用一次回调时,它工作得很好.但是当我调用回调两次时,它会给出 Segmentation fault (core dumped).使用 gdb 找不到错误.下面是 JS 和 C++ 代码(使用 node-gyp configure build 编译):

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++插件代码

//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;
};

推荐答案

你的类使用 AsyncQueueWorker 来调用 CallbackRunner,但是 AsyncQueueWorker 调用AsyncExecuteComplete 回调完成后,依次调用worker->Destroy().查看 nan.h 中的 AsyncQueueWorker 代码:

Your class uses AsyncQueueWorker to invoke the CallbackRunner, but AsyncQueueWorker calls AsyncExecuteComplete after the callback is done, which in turn calls worker->Destroy(). See the AsyncQueueWorker code from nan.h:

inline void AsyncExecute (uv_work_t* req) {
  AsyncWorker *worker = static_cast<AsyncWorker*>(req->data);
  worker->Execute();
}

inline void AsyncExecuteComplete (uv_work_t* req) {
  AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
  worker->WorkComplete();
  worker->Destroy();
}

inline void AsyncQueueWorker (AsyncWorker* worker) {
  uv_queue_work(
      uv_default_loop()
    , &worker->request
    , AsyncExecute
    , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
  );
}

worker->Destroy() 将删除 CallbackRunner 类,以及您提供给其构造函数的 Nan::Callback.这就是您在第二次尝试调用此回调时遇到分段错误的原因.

worker->Destroy() will delete the CallbackRunner class, along with the Nan::Callback that you fed to its constructor. That is the reason why you get a segmentation fault when attempting to call this callback a second time.

您最好将类基于 Nan::AsyncProgressQueueWorker 而不是 Nan::AsyncWorker.AsyncProgressQueueWorker 继承了 AsyncWorker,它允许你像 AsyncWorker 一样从主线程调度工作,但它为你提供了一个 ExecutionProgress 允许您在原始计划作业运行时使用任何线程任意次数回调主线程的类.

You might be better off basing your class on Nan::AsyncProgressQueueWorker instead of Nan::AsyncWorker. AsyncProgressQueueWorker inherits AsyncWorker and it allows you to schedule work from the main thread just as AsyncWorker does, but it provides you with an ExecutionProgress class 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::AsyncProgressQueueWorker2.8.0

这篇关于两次调用某个回调函数会导致分段错误:Nan的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆