2013-03-20 57 views
2

下面的代碼在OS X中起作用,但是當我編譯&在Ubuntu中運行時,在調用baton->callback函數時出現段錯誤。看起來Persistent<Function>不會超過最初的Aysnc::Start方法。Calling Persistent <Function> AfterWork中的回調段錯誤

如果是這樣,爲什麼它在OS X上工作? 我該怎麼做才能使其跨平臺工作

如果我做錯了,我需要做什麼才能使我的callback可以從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("Work\n"); 
} 

void Async::AfterWork(uv_work_t *req) { 
    printf("AfterWork\n"); 
    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); 
    } 
} 

回答

2

我不熟悉libuv,但鑑於你的Baton定義,假設傳遞到AfterWork()uv_work_t*是一樣的一個傳遞到uv_queue_work(),你delete req聲明實際上刪除您Baton結構,從然後嘗試讀取callback字段。我會嘗試刪除delete req並在AfterWork()的末尾添加delete baton