/ / Volanie pretrvávajúcich <Function> spätných volaní v AfterWork - node.js, v8

Volanie pretrvávajúcich <Function> spätných volaní v AfterWork - node.js, v8

Nižšie uvedený kód funguje v OS X, ale keď ho skompilujem a spustím v Ubuntu, pri volaní baton->callback Funkcie. Zdá sa, že Persistent<Function> nepretrváva mimo pôvodného stavu Aysnc::Start metóda.

Ak je to tak, prečo to funguje na OS X? Čo môžem urobiť, aby to fungovalo na viacerých platformách?

Ak to robím zle, čo musím urobiť, aby som si vytvoril callback volať z AfterWork?

// Async.h

#include <v8.h>
#include <node.h>
#include <string>

using namespace node;
using namespace v8;

class Async : public ObjectWrap {
public:
static Persistent<Function> constructor_template;
static void Initialize(Handle<v8::Object> target);

protected:
Async() {}
~Async() {}

static Handle<Value> Start(const Arguments& args);
static void Work(uv_work_t* req);
static void AfterWork(uv_work_t* req);
private:

struct Baton {
uv_work_t request;
Persistent<Function> callback;
};
};

// Async.cc
Handle<Value> Async::Start(const Arguments& args) {
HandleScope scope;

if(args.Length() == 0 || !args[0]->IsFunction()) {
return ThrowException(Exception::Error(String::New("Callback is required and must be a Function.")));
}

Baton *baton = new Baton();
baton->request.data = baton;
baton->callback = Persistent<Function>::New(Handle<Function>::Cast(args[0]));

uv_queue_work(uv_default_loop(), &baton->request, Work, (uv_after_work_cb)AfterWork);

return Undefined();
}

void Async::Work(uv_work_t *req) {
printf("Workn");
}

void Async::AfterWork(uv_work_t *req) {
printf("AfterWorkn");
HandleScope scope;

Baton *baton = static_cast<Baton *>(req->data);
delete req;

Local<Value> argv[1] = {
Local<Value>::New(Null());
};

TryCatch try_catch;
// Segfault occurs here
baton->callback->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
}

odpovede:

2 pre odpoveď č. 1

Nie som oboznámený libuv, ale podľa vašej definície Batona za predpokladu, že uv_work_t* prešiel do AfterWork() je rovnaká ako tá, do ktorej prešiel uv_queue_work(), vaše delete req vyhlásenie skutočne vymaže vaše Baton štruktúra, z ktorej sa potom pokúsite prečítať callback lúka. Skúsim odstrániť delete req a pridanie delete baton na samom konci mesta AfterWork().