From cbcacc24bf52546173082af1d718992372103a4a Mon Sep 17 00:00:00 2001 From: Adeel Date: Fri, 21 Nov 2014 14:51:59 +0200 Subject: [PATCH] libuv: Uses uv_async_send to dispatch callback. Dispatches callback to uv_default_loop. --- src/binding.cpp | 96 +++++++++++++++++++++++++------------- src/libsass | 2 +- src/sass_context_wrapper.h | 6 +++ 3 files changed, 70 insertions(+), 34 deletions(-) diff --git a/src/binding.cpp b/src/binding.cpp index 5a3aee602..c64e2ee16 100644 --- a/src/binding.cpp +++ b/src/binding.cpp @@ -2,61 +2,84 @@ #include "sass_context_wrapper.h" char* CreateString(Local value) { - if(value->IsNull() || !value->IsString()) { + if (value->IsNull() || !value->IsString()) { return const_cast(""); // return empty string. } String::Utf8Value string(value); - char *str = (char *) malloc(string.length() + 1); + char *str = (char *)malloc(string.length() + 1); strcpy(str, *string); return str; } -struct Sass_Import** sass_importer(const char* file, void* cookie) -{ +uv_async_t async; + +void dispatched_async_uv_callback(uv_async_t *req){ NanScope(); + TryCatch try_catch; + import_bag* bag = static_cast(req->data); + Handle argv[] = { - NanNew(file) + NanNew(bag->file) }; - Local returned_value = NanNew(((NanCallback*)cookie)->Call(2, argv)); + Local returned_value = NanNew(((NanCallback*)bag->cookie)->Call(1, argv)); - if(returned_value->IsArray()) { + if (returned_value->IsArray()) { Handle array = Handle::Cast(returned_value); - struct Sass_Import** incs = sass_make_import_list(array->Length()); + bag->incs = sass_make_import_list(array->Length()); - for(size_t i = 0; i < array->Length(); ++i) { + for (size_t i = 0; i < array->Length(); ++i) { Local value = array->Get(i); - if(!value->IsObject()) + if (!value->IsObject()) continue; Local object = Local::Cast(value); - char* path = CreateString(object->Get(String::New("path"))); + char* path = CreateString(object->Get(String::New("file"))); char* contents = CreateString(object->Get(String::New("contents"))); - incs[i] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0); + bag->incs[i] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0); } - - return incs; - } else if(returned_value->IsObject()) { - struct Sass_Import** incs = sass_make_import_list(1); + } + else if (returned_value->IsObject()) { + bag->incs = sass_make_import_list(1); Local object = Local::Cast(returned_value); - char* path = CreateString(object->Get(String::New("path"))); + char* path = CreateString(object->Get(String::New("file"))); char* contents = CreateString(object->Get(String::New("contents"))); - incs[0] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0); + bag->incs[0] = sass_make_import_entry(path, (!contents || contents[0] == '\0') ? 0 : strdup(contents), 0); + } + else { + bag->incs = sass_make_import_list(1); + bag->incs[0] = sass_make_import_entry(bag->file, 0, 0); + } - return incs; + if (try_catch.HasCaught()) { + node::FatalException(try_catch); } +} - struct Sass_Import** incs = sass_make_import_list(1); +struct Sass_Import** sass_importer(const char* file, void* cookie) +{ + import_bag* bag = (import_bag*)calloc(1, sizeof(import_bag)); + + bag->cookie = cookie; + bag->file = file; + + async.data = (void*)bag; + uv_async_send(&async); + + // Dispatch immediately + uv_run(async.loop, UV_RUN_DEFAULT); + + Sass_Import** import = bag->incs; - incs[0] = sass_make_import_entry(file, 0, 0); + free(bag); - return incs; + return import; } void ExtractOptions(Local options, void* cptr, sass_context_wrapper* ctx_w, bool isFile) { @@ -64,7 +87,8 @@ void ExtractOptions(Local options, void* cptr, sass_context_wrapper* ctx if (isFile) { ctx = sass_file_context_get_context((struct Sass_File_Context*) cptr); - } else { + } + else { ctx = sass_data_context_get_context((struct Sass_Data_Context*) cptr); } @@ -80,7 +104,8 @@ void ExtractOptions(Local options, void* cptr, sass_context_wrapper* ctx if (isFile) { ctx_w->fctx = (struct Sass_File_Context*) cptr; - } else { + } + else { ctx_w->dctx = (struct Sass_Data_Context*) cptr; } ctx_w->request.data = ctx_w; @@ -88,8 +113,10 @@ void ExtractOptions(Local options, void* cptr, sass_context_wrapper* ctx ctx_w->error_callback = new NanCallback(error_callback); ctx_w->importer_callback = new NanCallback(importer_callback); - if(!importer_callback->IsUndefined()) + if (!importer_callback->IsUndefined()){ sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w->importer_callback)); + uv_async_init(uv_default_loop(), &async, (uv_async_cb)dispatched_async_uv_callback); + } } sass_option_set_output_path(sass_options, CreateString(options->Get(NanNew("outFile")))); @@ -109,7 +136,7 @@ void FillStatsObj(Handle stats, Sass_Context* ctx) { char** included_files = sass_context_get_included_files(ctx); Handle arr = NanNew(); - if(included_files) { + if (included_files) { for (int i = 0; included_files[i] != nullptr; ++i) { arr->Set(i, NanNew(included_files[i])); } @@ -125,14 +152,15 @@ void FillStatsObj(Handle stats, Sass_Context* ctx) { if (sass_context_get_source_map_string(ctx)) { source_map = NanNew(sass_context_get_source_map_string(ctx)); - } else { + } + else { source_map = NanNew("{}"); } - (*stats)->Set(NanNew("sourceMap"), source_map); + (*stats)->Set(NanNew("sourceMap"), source_map); } -void MakeCallback(uv_work_t* req) { +void make_callback(uv_work_t* req) { NanScope(); TryCatch try_catch; @@ -144,7 +172,8 @@ void MakeCallback(uv_work_t* req) { ctx = sass_data_context_get_context(ctx_w->dctx); FillStatsObj(NanNew(ctx_w->stats), ctx); error_status = sass_context_get_error_status(ctx); - } else { + } + else { ctx = sass_file_context_get_context(ctx_w->fctx); FillStatsObj(NanNew(ctx_w->stats), ctx); error_status = sass_context_get_error_status(ctx); @@ -158,7 +187,8 @@ void MakeCallback(uv_work_t* req) { NanNew(ctx_w->stats)->Get(NanNew("sourceMap")) }; ctx_w->success_callback->Call(2, argv); - } else { + } + else { // if error, do callback(error) const char* err = sass_context_get_error_json(ctx); Local argv[] = { @@ -186,7 +216,7 @@ NAN_METHOD(Render) { ExtractOptions(options, dctx, ctx_w, false); - int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback); + int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)make_callback); assert(status == 0); @@ -231,7 +261,7 @@ NAN_METHOD(RenderFile) { ctx_w->fctx = fctx; ExtractOptions(options, fctx, ctx_w, true); - int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback); + int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)make_callback); assert(status == 0); free(input_path); diff --git a/src/libsass b/src/libsass index 5f3558d7c..21688e197 160000 --- a/src/libsass +++ b/src/libsass @@ -1 +1 @@ -Subproject commit 5f3558d7ce36bb61202f1585ed8e32a52209e940 +Subproject commit 21688e1979bff089a13d9a44ad0608357b2a91cc diff --git a/src/sass_context_wrapper.h b/src/sass_context_wrapper.h index 6fdeded5c..a86fb2b5c 100644 --- a/src/sass_context_wrapper.h +++ b/src/sass_context_wrapper.h @@ -21,6 +21,12 @@ struct sass_context_wrapper { NanCallback* importer_callback; }; +struct import_bag { + const char* file; + void* cookie; + Sass_Import** incs; +}; + struct sass_context_wrapper* sass_make_context_wrapper(void); void sass_free_context_wrapper(struct sass_context_wrapper* ctx_w);