Created
February 27, 2015 19:17
-
-
Save johnhaley81/24686896ea2fed936ac3 to your computer and use it in GitHub Desktop.
`uv_async_init`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PAYLOAD_WRAPPER_H | |
#define PAYLOAD_WRAPPER_H | |
#include <v8.h> | |
#include <node.h> | |
#include "nan.h" | |
using namespace v8; | |
using namespace node; | |
struct PayloadWrapper { | |
NanCallback* jsCallback; | |
uv_async_t handle; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is run in the main loop | |
NAN_METHOD(GitStatus::ForeachExt) | |
{ | |
NanScope(); | |
ForeachExtBaton* baton = new ForeachExtBaton; | |
baton->error_code = GIT_OK; | |
baton->error = NULL; | |
ForeachExt_globalPayload* globalPayload = new ForeachExt_globalPayload; | |
git_repository * from_repo; | |
from_repo = ObjectWrap::Unwrap<GitRepository>(args[0]->ToObject())->GetValue(); | |
baton->repo = from_repo; | |
const git_status_options * from_opts; | |
from_opts = ObjectWrap::Unwrap<GitStatusOptions>(args[1]->ToObject())->GetValue(); | |
baton->opts = from_opts; | |
baton->callback = ForeachExt_callback_cppCallback; | |
globalPayload->callback = new PayloadWrapper(); | |
globalPayload->callback->jsCallback = new NanCallback(args[2].As<Function>()); | |
uv_async_init(uv_default_loop(), &globalPayload->callback->handle, ForeachExt_callback_async); | |
baton->payload = globalPayload; | |
NanCallback *callback = new NanCallback(Local<Function>::Cast(args[4])); | |
ForeachExtWorker *worker = new ForeachExtWorker(baton, callback); | |
if (!args[0]->IsUndefined() && !args[0]->IsNull()) { | |
worker->SaveToPersistent("repo", args[0]->ToObject()); | |
} | |
if (!args[1]->IsUndefined() && !args[1]->IsNull()) { | |
worker->SaveToPersistent("opts", args[1]->ToObject()); | |
} | |
if (!args[3]->IsUndefined() && !args[3]->IsNull()) { | |
worker->SaveToPersistent("payload", args[3]->ToObject()); | |
} | |
NanAsyncQueueWorker(worker); | |
NanReturnUndefined(); | |
} | |
// This is run outside of the main loop | |
void GitStatus::ForeachExtWorker::Execute() | |
{ | |
int result = git_status_foreach_ext( | |
baton->repo,baton->opts,baton->callback,baton->payload ); | |
baton->error_code = result; | |
if (result != GIT_OK && giterr_last() != NULL) { | |
baton->error = git_error_dup(giterr_last()); | |
} | |
} | |
// This is run in the main loop | |
void GitStatus::ForeachExtWorker::HandleOKCallback() | |
{ | |
TryCatch try_catch; | |
if (baton->error_code == GIT_OK) { | |
Handle<v8::Value> result = NanUndefined(); | |
Handle<v8::Value> argv[2] = { | |
NanNull(), | |
result | |
}; | |
callback->Call(2, argv); | |
} else { | |
if (baton->error) { | |
Handle<v8::Value> argv[1] = { | |
NanError(baton->error->message) | |
}; | |
callback->Call(1, argv); | |
if (baton->error->message) | |
free((void *)baton->error->message); | |
free((void *)baton->error); | |
} else { | |
callback->Call(0, NULL); | |
} | |
} | |
if (try_catch.HasCaught()) { | |
node::FatalException(try_catch); | |
} | |
delete (ForeachExt_globalPayload*)baton->payload; | |
delete baton; | |
} | |
// This is run outside of the main loop | |
int GitStatus::ForeachExt_callback_cppCallback ( | |
const char * path, unsigned int status_flags, void * payload ) | |
{ | |
ForeachExt_CallbackBaton* baton = new ForeachExt_CallbackBaton(); | |
baton->path = path; | |
baton->status_flags = status_flags; | |
baton->payload = payload; | |
baton->req = &((ForeachExt_globalPayload*)payload)->callback->handle; | |
baton->result = 0; | |
baton->req->data = baton; | |
baton->done = false; | |
uv_async_send(baton->req); | |
while(!baton->done) { | |
this_thread::sleep_for(chrono::milliseconds(1)); | |
} | |
return baton->result; | |
} | |
// This is run in the main loop | |
void GitStatus::ForeachExt_callback_async(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
ForeachExt_CallbackBaton* baton = static_cast<ForeachExt_CallbackBaton*>(req->data); | |
NanCallback* callback = ((ForeachExt_globalPayload*)baton->payload)->callback->jsCallback; | |
Local<Value> argv[3] = { | |
NanNew(baton->path), | |
NanNew(baton->status_flags), | |
NanUndefined() | |
}; | |
TryCatch tryCatch; | |
Handle<v8::Value> result = callback->Call(3, argv); | |
if (result.IsEmpty() || result->IsNativeError()) { | |
baton->result = -1; | |
} else if (!result->IsNull() && !result->IsUndefined()) { | |
if (result->IsNumber()) { | |
baton->result = (int)result->ToNumber()->Value(); | |
} else { | |
baton->result = 0; | |
} | |
} else { | |
baton->result = 0; | |
} | |
baton->done = true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GITSTATUS_H | |
#define GITSTATUS_H | |
// generated from class_header.h | |
#include <nan.h> | |
#include <string> | |
extern "C" { | |
#include <git2.h> | |
#include <git2/sys/diff.h> | |
} | |
#include "../include/repository.h" | |
#include "../include/status_options.h" | |
#include "payload_wrapper.h" | |
using namespace node; | |
using namespace v8; | |
class GitStatus : public ObjectWrap { | |
public: | |
static Persistent<Function> constructor_template; | |
static void InitializeComponent (Handle<v8::Object> target); | |
static void ForeachExt_callback_async(uv_async_t* req, int status); | |
struct ForeachExt_CallbackBaton { | |
const char * path; | |
unsigned int status_flags; | |
void * payload; | |
uv_async_t* req; | |
int result; | |
Persistent<Object> promise; | |
bool done; | |
}; | |
private: | |
struct ForeachExtBaton { | |
int error_code; | |
const git_error* error; | |
git_repository * repo; | |
const git_status_options * opts; | |
git_status_cb callback; | |
void * payload; | |
}; | |
class ForeachExtWorker : public NanAsyncWorker { | |
public: | |
ForeachExtWorker( | |
ForeachExtBaton *_baton, | |
NanCallback *callback | |
) : NanAsyncWorker(callback) | |
, baton(_baton) {}; | |
~ForeachExtWorker() {}; | |
void Execute(); | |
void HandleOKCallback(); | |
private: | |
ForeachExtBaton *baton; | |
}; | |
static NAN_METHOD(ForeachExt); | |
struct ForeachExt_globalPayload { | |
PayloadWrapper * callback; | |
ForeachExt_globalPayload() { | |
callback = NULL; | |
} | |
~ForeachExt_globalPayload() { | |
if (callback != NULL) { | |
delete callback; | |
} | |
} | |
}; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment