diff --git a/src/HttpResponseWrapper.h b/src/HttpResponseWrapper.h index 83eb6aaec..e5bf3421a 100644 --- a/src/HttpResponseWrapper.h +++ b/src/HttpResponseWrapper.h @@ -222,19 +222,21 @@ struct HttpResponseWrapper { Isolate *isolate = args.GetIsolate(); auto *res = getHttpResponse(args); if (res) { - /* This thing perfectly fits in with unique_function, and will Reset on destructor */ - UniquePersistent p(isolate, Local::Cast(args[0])); + /* The callback lives in internal field 1 of res, so one global handle per request instead of two */ + args.This()->SetInternalField(1, args[0]); /* This is how we capture res (C++ this in invocation of this function) */ UniquePersistent resObject(isolate, args.This()); - res->onAborted([p = std::move(p), resObject = std::move(resObject), isolate]() { + res->onAborted([resObject = std::move(resObject), isolate]() { HandleScope hs(isolate); + Local resLocal = Local::New(isolate, resObject); + /* Mark this resObject invalid */ - setInternalPointer(Local::New(isolate, resObject), nullptr);//->SetAlignedPointerInInternalField(0, nullptr); + setInternalPointer(resLocal, nullptr); - CallJS(isolate, Local::New(isolate, p), 0, nullptr); + CallJS(isolate, Local::Cast(resLocal->GetInternalField(1).As()), 0, nullptr); }); args.GetReturnValue().Set(args.This()); @@ -587,7 +589,8 @@ struct HttpResponseWrapper { } else if (SSL == 3) { resTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpCacheResponse", NewStringType::kNormal).ToLocalChecked()); } - resTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1); + /* Field 0 is the native pointer, field 1 holds the onAborted callback */ + resTemplateLocal->InstanceTemplate()->SetInternalFieldCount(2); /* Register our functions (the most common go here) */ resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "end", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_end));