Created
April 20, 2015 18:04
-
-
Save johnhaley81/938dcfa4975b9e92c085 to your computer and use it in GitHub Desktop.
Trying out fixing cross thread calling in nodegit
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 a generated file, modify: generate/templates/struct_content.cc. | |
#include <nan.h> | |
#include <string.h> | |
#include <chrono> | |
#include <thread> | |
extern "C" { | |
#include <git2.h> | |
} | |
#include <iostream> | |
#include "../include/functions/copy.h" | |
#include "../include/remote_callbacks.h" | |
#include "../include/cred.h" | |
#include "../include/cert.h" | |
#include "../include/transfer_progress.h" | |
using namespace v8; | |
using namespace node; | |
using namespace std; | |
// generated from struct_content.cc | |
GitRemoteCallbacks::GitRemoteCallbacks() | |
{ | |
git_remote_callbacks wrappedValue = GIT_REMOTE_CALLBACKS_INIT; | |
this->raw = (git_remote_callbacks*) malloc(sizeof(git_remote_callbacks)); | |
memcpy(this->raw, &wrappedValue, sizeof(git_remote_callbacks)); | |
this->ConstructFields(); | |
this->selfFreeing = true; | |
} | |
GitRemoteCallbacks::GitRemoteCallbacks(git_remote_callbacks* raw, bool selfFreeing) | |
{ | |
this->raw = raw; | |
this->ConstructFields(); | |
this->selfFreeing = selfFreeing; | |
} | |
GitRemoteCallbacks::~GitRemoteCallbacks() | |
{ | |
if (this->credentials != NULL) { | |
delete this->credentials; | |
this->raw->payload = NULL; | |
} | |
if (this->certificate_check != NULL) { | |
delete this->certificate_check; | |
this->raw->payload = NULL; | |
} | |
if (this->transfer_progress != NULL) { | |
delete this->transfer_progress; | |
this->raw->payload = NULL; | |
} | |
if (this->selfFreeing) { | |
free(this->raw); | |
} | |
} | |
void GitRemoteCallbacks::ConstructFields() | |
{ | |
// Set the static method call and set the payload for this function to be | |
// the current instance | |
this->raw->credentials = NULL; | |
this->raw->payload = (void *)this; | |
this->credentials = NULL; | |
// Set the static method call and set the payload for this function to be | |
// the current instance | |
this->raw->certificate_check = NULL; | |
this->raw->payload = (void *)this; | |
this->certificate_check = NULL; | |
// Set the static method call and set the payload for this function to be | |
// the current instance | |
this->raw->transfer_progress = NULL; | |
this->raw->payload = (void *)this; | |
this->transfer_progress = NULL; | |
Local<Value> payload = NanUndefined(); | |
NanAssignPersistent(this->payload, payload); | |
} | |
void GitRemoteCallbacks::InitializeComponent(Handle<v8::Object> target) | |
{ | |
NanScope(); | |
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(JSNewFunction); | |
tpl->InstanceTemplate()->SetInternalFieldCount(1); | |
tpl->SetClassName(NanNew<String>("RemoteCallbacks")); | |
tpl->InstanceTemplate()->SetAccessor(NanNew<String>("version"), GetVersion, SetVersion); | |
tpl->InstanceTemplate()->SetAccessor(NanNew<String>("credentials"), GetCredentials, SetCredentials); | |
tpl->InstanceTemplate()->SetAccessor(NanNew<String>("certificateCheck"), GetCertificateCheck, SetCertificateCheck); | |
tpl->InstanceTemplate()->SetAccessor(NanNew<String>("transferProgress"), GetTransferProgress, SetTransferProgress); | |
Local<Function> _constructor_template = tpl->GetFunction(); | |
NanAssignPersistent(constructor_template, _constructor_template); | |
target->Set(NanNew<String>("RemoteCallbacks"), _constructor_template); | |
} | |
NAN_METHOD(GitRemoteCallbacks::JSNewFunction) | |
{ | |
NanScope(); | |
GitRemoteCallbacks* instance; | |
if (args.Length() == 0 || !args[0]->IsExternal()) { | |
instance = new GitRemoteCallbacks(); | |
} else { | |
instance = new GitRemoteCallbacks(static_cast<git_remote_callbacks*>(Handle<External>::Cast(args[0])->Value()), args[1]->BooleanValue()); | |
} | |
instance->Wrap(args.This()); | |
NanReturnValue(args.This()); | |
} | |
Handle<v8::Value> GitRemoteCallbacks::New(void* raw, bool selfFreeing) | |
{ | |
NanEscapableScope(); | |
Handle<v8::Value> argv[2] = { NanNew<External>((void *)raw), NanNew<Boolean>(selfFreeing) }; | |
return NanEscapeScope(NanNew<Function>(GitRemoteCallbacks::constructor_template)->NewInstance(2, argv)); | |
} | |
git_remote_callbacks *GitRemoteCallbacks::GetValue() | |
{ | |
return this->raw; | |
} | |
git_remote_callbacks **GitRemoteCallbacks::GetRefValue() | |
{ | |
return this->raw == NULL ? NULL : &this->raw; | |
} | |
void GitRemoteCallbacks::ClearValue() | |
{ | |
this->raw = NULL; | |
} | |
NAN_GETTER(GitRemoteCallbacks::GetVersion) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanReturnValue(NanNew<Number>(wrapper->GetValue()->version)); | |
} | |
NAN_SETTER(GitRemoteCallbacks::SetVersion) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
if (value->IsNumber()) { | |
wrapper->GetValue()->version = (unsigned int) value->Int32Value(); | |
} | |
} | |
NAN_GETTER(GitRemoteCallbacks::GetCredentials) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanReturnValue(wrapper->credentials->GetFunction()); | |
} | |
NAN_SETTER(GitRemoteCallbacks::SetCredentials) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
if (wrapper->credentials != NULL) { | |
delete wrapper->credentials; | |
} | |
if (value->IsFunction()) { | |
if (!wrapper->raw->credentials) { | |
wrapper->raw->credentials = (git_cred_acquire_cb)credentials_cppCallback; | |
} | |
CredentialsBaton* baton = new CredentialsBaton(); | |
baton->result = 0; | |
baton->req.data = baton; | |
baton->done = false; | |
baton->payload = wrapper; | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) credentials_async); | |
wrapper->raw->payload = baton; | |
wrapper->credentials = new NanCallback(value.As<Function>()); | |
} | |
NanReturnUndefined(); | |
} | |
int GitRemoteCallbacks::credentials_cppCallback ( | |
git_cred ** cred, const char * url, const char * username_from_url, unsigned int allowed_types, void * payload ) | |
{ | |
CredentialsBaton* baton = (CredentialsBaton*) payload; | |
baton->cred = cred; | |
baton->url = url; | |
baton->username_from_url = username_from_url; | |
baton->allowed_types = allowed_types; | |
uv_async_send(&baton->req); | |
while(!baton->done) { | |
this_thread::sleep_for(chrono::milliseconds(1)); | |
} | |
*cred = *baton->cred; | |
return baton->result; | |
} | |
void GitRemoteCallbacks::credentials_async(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
CredentialsBaton* baton = static_cast<CredentialsBaton*>(req->data); | |
GitRemoteCallbacks* instance = static_cast<GitRemoteCallbacks*>(baton->payload); | |
if (instance->credentials->IsEmpty()) { | |
baton->result = 1; // no results acquired | |
baton->done = true; | |
return; | |
} | |
if (baton->url == NULL) { | |
baton->url = ""; | |
} | |
if (baton->username_from_url == NULL) { | |
baton->username_from_url = ""; | |
} | |
if (baton->allowed_types == NULL) { | |
baton->allowed_types = 0; | |
} | |
Local<Value> argv[4] = { | |
NanNew(baton->url), | |
NanNew(baton->username_from_url), | |
NanNew(baton->allowed_types), | |
NanNew(instance->payload) | |
}; | |
TryCatch tryCatch; | |
Handle<v8::Value> result = instance->credentials->Call(4, argv); | |
if (result->IsObject() && result->ToObject()->Has(NanNew("then"))) { | |
Handle<v8::Value> thenProp = result->ToObject()->Get(NanNew("then")); | |
if (thenProp->IsFunction()) { | |
// we can be reasonbly certain that the result is a promise | |
Local<Object> promise = result->ToObject(); | |
NanAssignPersistent(baton->promise, promise); | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) credentials_asyncPromisePolling); | |
uv_async_send(&baton->req); | |
return; | |
} | |
} | |
if (result.IsEmpty() || result->IsNativeError()) { | |
baton->result = -1; | |
} else if (!result->IsNull() && !result->IsUndefined()) { | |
GitCred* wrapper = ObjectWrap::Unwrap<GitCred>(result->ToObject()); | |
wrapper->selfFreeing = false; | |
baton->cred = wrapper->GetRefValue(); | |
baton->result = 0; | |
} else { | |
baton->result = 1; | |
} | |
uv_close((uv_handle_t*) &baton->req, NULL); | |
baton->done = true; | |
NanReturnUndefined(); | |
} | |
void GitRemoteCallbacks::credentials_asyncPromisePolling(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
CredentialsBaton* baton = static_cast<CredentialsBaton*>(req->data); | |
Local<Object> promise = NanNew<Object>(baton->promise); | |
NanCallback* isPendingFn = new NanCallback(promise->Get(NanNew("isPending")).As<Function>()); | |
Local<Value> argv[1]; // MSBUILD won't assign an array of length 0 | |
Local<Boolean> isPending = isPendingFn->Call(0, argv)->ToBoolean(); | |
if (isPending->Value()) { | |
uv_async_send(&baton->req); | |
return; | |
} | |
NanCallback* isFulfilledFn = new NanCallback(promise->Get(NanNew("isFulfilled")).As<Function>()); | |
Local<Boolean> isFulfilled = isFulfilledFn->Call(0, argv)->ToBoolean(); | |
if (isFulfilled->Value()) { | |
NanCallback* resultFn = new NanCallback(promise->Get(NanNew("value")).As<Function>()); | |
Handle<v8::Value> result = resultFn->Call(0, argv); | |
if (result.IsEmpty() || result->IsNativeError()) { | |
baton->result = -1; | |
} else if (!result->IsNull() && !result->IsUndefined()) { | |
GitCred* wrapper = ObjectWrap::Unwrap<GitCred>(result->ToObject()); | |
wrapper->selfFreeing = false; | |
baton->cred = wrapper->GetRefValue(); | |
baton->result = 0; | |
} else { | |
baton->result = 1; | |
} | |
} else { | |
// promise was rejected | |
baton->result = -1; | |
} | |
baton->done = true; | |
NanReturnUndefined(); | |
} | |
NAN_GETTER(GitRemoteCallbacks::GetCertificateCheck) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanReturnValue(wrapper->certificate_check->GetFunction()); | |
} | |
NAN_SETTER(GitRemoteCallbacks::SetCertificateCheck) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
if (wrapper->certificate_check != NULL) { | |
delete wrapper->certificate_check; | |
} | |
if (value->IsFunction()) { | |
if (!wrapper->raw->certificate_check) { | |
wrapper->raw->certificate_check = (git_transport_certificate_check_cb)certificate_check_cppCallback; | |
} | |
wrapper->certificate_check = new NanCallback(value.As<Function>()); | |
} | |
NanReturnUndefined(); | |
} | |
int GitRemoteCallbacks::certificate_check_cppCallback ( | |
git_cert * cert, int valid, const char * host, void * payload ) | |
{ | |
CertificateCheckBaton* baton = new CertificateCheckBaton(); | |
baton->cert = cert; | |
baton->valid = valid; | |
baton->host = host; | |
baton->payload = payload; | |
baton->result = 0; | |
baton->req.data = baton; | |
baton->done = false; | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) certificate_check_async); | |
uv_async_send(&baton->req); | |
while(!baton->done) { | |
this_thread::sleep_for(chrono::milliseconds(1)); | |
} | |
return baton->result; | |
} | |
void GitRemoteCallbacks::certificate_check_async(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
CertificateCheckBaton* baton = static_cast<CertificateCheckBaton*>(req->data); | |
GitRemoteCallbacks* instance = static_cast<GitRemoteCallbacks*>(baton->payload); | |
if (instance->certificate_check->IsEmpty()) { | |
baton->result = 1; // no results acquired | |
baton->done = true; | |
return; | |
} | |
if (baton->cert == NULL) { | |
} | |
if (baton->valid == NULL) { | |
} | |
if (baton->host == NULL) { | |
baton->host = ""; | |
} | |
Local<Value> argv[4] = { | |
NanNew(GitCert::New((void *)baton->cert, false)), | |
NanNew(baton->valid), | |
NanNew(baton->host), | |
NanNew(instance->payload) | |
}; | |
TryCatch tryCatch; | |
Handle<v8::Value> result = instance->certificate_check->Call(4, argv); | |
if (result->IsObject() && result->ToObject()->Has(NanNew("then"))) { | |
Handle<v8::Value> thenProp = result->ToObject()->Get(NanNew("then")); | |
if (thenProp->IsFunction()) { | |
// we can be reasonbly certain that the result is a promise | |
Local<Object> promise = result->ToObject(); | |
NanAssignPersistent(baton->promise, promise); | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) certificate_check_asyncPromisePolling); | |
uv_async_send(&baton->req); | |
return; | |
} | |
} | |
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 = 1; | |
} | |
} else { | |
baton->result = 1; | |
} | |
baton->done = true; | |
NanReturnUndefined(); | |
} | |
void GitRemoteCallbacks::certificate_check_asyncPromisePolling(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
CertificateCheckBaton* baton = static_cast<CertificateCheckBaton*>(req->data); | |
Local<Object> promise = NanNew<Object>(baton->promise); | |
NanCallback* isPendingFn = new NanCallback(promise->Get(NanNew("isPending")).As<Function>()); | |
Local<Value> argv[1]; // MSBUILD won't assign an array of length 0 | |
Local<Boolean> isPending = isPendingFn->Call(0, argv)->ToBoolean(); | |
if (isPending->Value()) { | |
uv_async_send(&baton->req); | |
return; | |
} | |
NanCallback* isFulfilledFn = new NanCallback(promise->Get(NanNew("isFulfilled")).As<Function>()); | |
Local<Boolean> isFulfilled = isFulfilledFn->Call(0, argv)->ToBoolean(); | |
if (isFulfilled->Value()) { | |
NanCallback* resultFn = new NanCallback(promise->Get(NanNew("value")).As<Function>()); | |
Handle<v8::Value> result = resultFn->Call(0, 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 = 1; | |
} | |
} else { | |
baton->result = 1; | |
} | |
baton->done = true; | |
} else { | |
// promise was rejected | |
baton->result = -1; | |
baton->done = false; | |
} | |
} | |
NAN_GETTER(GitRemoteCallbacks::GetTransferProgress) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanReturnValue(wrapper->transfer_progress->GetFunction()); | |
} | |
NAN_SETTER(GitRemoteCallbacks::SetTransferProgress) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
if (wrapper->transfer_progress != NULL) { | |
delete wrapper->transfer_progress; | |
} | |
if (value->IsFunction()) { | |
if (!wrapper->raw->transfer_progress) { | |
wrapper->raw->transfer_progress = (git_transfer_progress_cb)transfer_progress_cppCallback; | |
} | |
wrapper->transfer_progress = new NanCallback(value.As<Function>()); | |
} | |
} | |
int GitRemoteCallbacks::transfer_progress_cppCallback ( | |
const git_transfer_progress * stats, void * payload ) | |
{ | |
TransferProgressBaton* baton = new TransferProgressBaton(); | |
baton->stats = stats; | |
baton->payload = payload; | |
baton->result = 0; | |
baton->req.data = baton; | |
baton->done = false; | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) transfer_progress_async); | |
uv_async_send(&baton->req); | |
while(!baton->done) { | |
this_thread::sleep_for(chrono::milliseconds(1)); | |
} | |
return baton->result; | |
} | |
void GitRemoteCallbacks::transfer_progress_async(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
TransferProgressBaton* baton = static_cast<TransferProgressBaton*>(req->data); | |
GitRemoteCallbacks* instance = static_cast<GitRemoteCallbacks*>(baton->payload); | |
if (instance->transfer_progress->IsEmpty()) { | |
baton->result = 0; // no results acquired | |
baton->done = true; | |
return; | |
} | |
if (baton->stats == NULL) { | |
} | |
Local<Value> argv[2] = { | |
NanNew(GitTransferProgress::New((void *)baton->stats, false)), | |
NanNew(instance->payload) | |
}; | |
TryCatch tryCatch; | |
Handle<v8::Value> result = instance->transfer_progress->Call(2, argv); | |
if (result->IsObject() && result->ToObject()->Has(NanNew("then"))) { | |
Handle<v8::Value> thenProp = result->ToObject()->Get(NanNew("then")); | |
if (thenProp->IsFunction()) { | |
// we can be reasonbly certain that the result is a promise | |
Local<Object> promise = result->ToObject(); | |
NanAssignPersistent(baton->promise, promise); | |
uv_async_init(uv_default_loop(), &baton->req, (uv_async_cb) transfer_progress_asyncPromisePolling); | |
uv_async_send(&baton->req); | |
return; | |
} | |
} | |
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; | |
} | |
void GitRemoteCallbacks::transfer_progress_asyncPromisePolling(uv_async_t* req, int status) | |
{ | |
NanScope(); | |
TransferProgressBaton* baton = static_cast<TransferProgressBaton*>(req->data); | |
Local<Object> promise = NanNew<Object>(baton->promise); | |
NanCallback* isPendingFn = new NanCallback(promise->Get(NanNew("isPending")).As<Function>()); | |
Local<Value> argv[1]; // MSBUILD won't assign an array of length 0 | |
Local<Boolean> isPending = isPendingFn->Call(0, argv)->ToBoolean(); | |
if (isPending->Value()) { | |
uv_async_send(&baton->req); | |
return; | |
} | |
NanCallback* isFulfilledFn = new NanCallback(promise->Get(NanNew("isFulfilled")).As<Function>()); | |
Local<Boolean> isFulfilled = isFulfilledFn->Call(0, argv)->ToBoolean(); | |
if (isFulfilled->Value()) { | |
NanCallback* resultFn = new NanCallback(promise->Get(NanNew("value")).As<Function>()); | |
Handle<v8::Value> result = resultFn->Call(0, 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; | |
} else { | |
// promise was rejected | |
baton->result = -1; | |
baton->done = false; | |
} | |
} | |
NAN_GETTER(GitRemoteCallbacks::GetPayload) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanReturnValue(wrapper->payload); | |
} | |
NAN_SETTER(GitRemoteCallbacks::SetPayload) | |
{ | |
NanScope(); | |
GitRemoteCallbacks *wrapper = ObjectWrap::Unwrap<GitRemoteCallbacks>(args.This()); | |
NanAssignPersistent(wrapper->payload, value); | |
} | |
Persistent<Function> GitRemoteCallbacks::constructor_template; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment