我发现在ObjectWrap类中使用ThreadSafeFunction会阻止事件循环退出,即使程序已经完成。只要我删除使用ThreadSafeFunction的函数(onScanStart和onScanStop),它就可以正确退出。但是当使用ThreadSafeFunction时,程序会继续运行,直到我按下CTRL+C。
下面是我使用的部分代码。如果你能帮我找出问题所在我会很感激
class AdapterWrapper : public Napi::ObjectWrap<Adapter> {
public:
static Napi::Object Init(Napi::Env env, Napi::Object exports);
AdapterWrapper(const Napi::CallbackInfo &info);
~AdapterWrapper();
static Napi::FunctionReference constructor;
private:
adapter_t handle;
Napi::ThreadSafeFunction onScanStartFn;
Napi::ThreadSafeFunction onScanStopFn;
static void onScanStart(adapter_t handle, void *userdata);
static void onScanStop(adapter_t handle, void *userdata);
Napi::Value Scan(const Napi::CallbackInfo &info);
void SetOnScanStart(const Napi::CallbackInfo &info);
void SetOnScanStop(const Napi::CallbackInfo &info);
};
Napi::FunctionReference AdapterWrapper::constructor;
Napi::Object AdapterWrapper::Init(Napi::Env env, Napi::Object exports) {
Napi::Function func = DefineClass(env, "Adapter", {
InstanceMethod("scan", &AdapterWrapper::ScanStart),
InstanceMethod("setOnScanStart", &AdapterWrapper::SetOnScanStart),
InstanceMethod("setOnScanStop", &AdapterWrapper::SetOnScanStop)
});
constructor = Napi::Persistent(func);
constructor.SuppressDestruct();
exports.Set("Adapter", func);
return exports;
}
AdapterWrapper::AdapterWrapper(const Napi::CallbackInfo &info)
: Napi::ObjectWrap<AdapterWrapper>(info) {
Napi::Env env = info.Env();
this->handle = adapter_get_handle();
}
AdapterWrapper::~AdapterWrapper() {
adapter_release_handle(this->handle);
if (this->onScanStartFn) {
this->onScanStartFn.Release();
}
if (this->onScanStopFn) {
this->onScanStopFn.Release();
}
}
Napi::Value AdapterWrapper::SetOnScanStart(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
this->onScanStartFn = Napi::ThreadSafeFunction::New(env, info[0].As<Napi::Function>(), "onScanStartFn", 0, 1);
adapter_set_on_scan_start(this->handle, onScanStart, this);
}
Napi::Value AdapterWrapper::SetOnScanStop(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
this->onScanStopFn = Napi::ThreadSafeFunction::New(env, info[0].As<Napi::Function>(), "onScanStopFn", 0, 1);
adapter_set_on_scan_stop(this->handle, onScanStop, this);
}
void AdapterWrapper::onScanStart(adapter_t handle, void *userdata) {
auto adapter = reinterpret_cast<AdapterWrapper *>(userdata);
auto callback = [](Napi::Env env, Napi::Function jsCallback) {
jsCallback.Call({});
};
onScanStartFn.BlockingCall(callback);
}
void AdapterWrapper::onScanStop(adapter_t handle, void *userdata) {
auto adapter = reinterpret_cast<AdapterWrapper *>(userdata);
auto callback = [](Napi::Env env, Napi::Function jsCallback) {
jsCallback.Call({});
};
adapter->onScanStopFn.BlockingCall(callback);
}
1条答案
按热度按时间xmq68pz91#
答案是在创建每个ThreadSafeFunction之后调用
Unref
。这告诉事件循环,一旦程序完成,它就可以被垃圾回收,而不会改变行为。HandleScope
也是为了额外的安全性而添加的。修改后的源代码: