1
ループから定期的にコールバックを行うネイティブNodeJSモジュールを作成しようとしています。私はコールバックを作るためにメインスレッドに戻るために必要なlibuvビットの周りに頭を抱えていると思っていますが、カルバックを作る瞬間にまだsigsegvでクラッシュしています。Native to NodeJSコールバック
test_sbio.cpp:
#include <node.h>
#include "SBIONative.h"
namespace sbio {
using v8::Local;
using v8::Object;
void InitAll(Local<Object> exports) {
SBIONative::Init(exports);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
}
SBIONative.h:
#ifndef SBIONative_H
#define SBIONative_H
#include <iostream>
#include <unistd.h>
#include <uv.h>
#include <node.h>
#include <node_object_wrap.h>
namespace sbio {
class SBIONative : public node::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
private:
explicit SBIONative();
~SBIONative();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Persistent<v8::Function> constructor;
static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void loop(void *arg);
static void asyncmsg(uv_async_t* handle);
v8::Persistent<v8::Function> cb;
bool run_;
uv_async_t async;
uv_thread_t event_loop;
};
}
#endif
SBIONative.cpp:
#include <SBIONative.h>
namespace sbio {
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::HandleScope;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;
Persistent<Function> SBIONative::constructor;
SBIONative::SBIONative() {
}
SBIONative::~SBIONative() {
}
void SBIONative::Init(Local<Object> exports) {
Isolate* isolate = exports->GetIsolate();
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
tpl->SetClassName(String::NewFromUtf8(isolate, "SBIONative"));
tpl->InstanceTemplate()->SetInternalFieldCount(2);
// Prototype
NODE_SET_PROTOTYPE_METHOD(tpl, "start", Start);
NODE_SET_PROTOTYPE_METHOD(tpl, "stop", Stop);
constructor.Reset(isolate, tpl->GetFunction());
exports->Set(String::NewFromUtf8(isolate, "SBIONative"),
tpl->GetFunction());
}
void SBIONative::New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.IsConstructCall()) {
// Invoked as constructor: `new MyObject(...)`
SBIONative* obj = new SBIONative();
obj->Wrap(args.This());
args.GetReturnValue().Set(args.This());
uv_loop_t* loop = uv_default_loop();
uv_async_init(loop, &obj->async, asyncmsg);
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Context> context = isolate->GetCurrentContext();
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Object> result =
cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(result);
}
}
void SBIONative::Start(const FunctionCallbackInfo<Value>& args) {
std::cout << "Start\n";
Isolate* isolate = args.GetIsolate();
SBIONative* obj = ObjectWrap::Unwrap<SBIONative>(args.Holder());
obj->run_ = true;
Local<Function> callback = Local<v8::Function>::Cast(args[0]);
obj->cb.Reset(isolate, callback);
uv_thread_create(&obj->event_loop, SBIONative::loop, (void*)obj);
}
void SBIONative::Stop(const FunctionCallbackInfo<Value>& args) {
std::cout << "Stop\n";
SBIONative* obj = ObjectWrap::Unwrap<SBIONative>(args.Holder());
obj->run_ = false;
uv_close((uv_handle_t*) &obj->async, NULL);
}
void SBIONative::loop(void *arg) {
SBIONative* obj = (SBIONative*)arg;
while(obj->run_) {
usleep(1 * 1000 * 1000);
std::cout << "loop\n";
obj->async.data = &obj->cb;
uv_async_send(&obj->async);
}
std::cout << "after loop" << std::endl;
}
void SBIONative::asyncmsg(uv_async_t* handle) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
Local<Value> argv[] = { v8::String::NewFromUtf8(isolate, "Hello world") };
//TODO This breaks here
((v8::Function*)handle->data)->Call(isolate->GetCurrentContext()->Global(), 1, argv);
std::cout << "callback" << std::endl;
}
}
私はMac上でそれを構築する場合、これは同じ場所で失敗しますLinux上で動作します。今日までの私の推測は、オブジェクトにコールバックを格納すること、またはそれをキャストすることです。