Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[squash] ABI/API compat
  • Loading branch information
addaleax committed Jul 11, 2017
commit 85597ca7b09b6573561312ea7aa2d93d4a3d2bee
60 changes: 57 additions & 3 deletions src/async-wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,10 @@ void AsyncWrap::AsyncReset(bool silent) {

if (silent) return;

EmitAsyncInit(env(), object(),
env()->async_hooks()->provider_string(provider_type()),
async_id_, trigger_id_);
AsyncWrap::EmitAsyncInit(
env(), object(),
env()->async_hooks()->provider_string(provider_type()),
async_id_, trigger_id_);
}


Expand Down Expand Up @@ -791,3 +792,56 @@ void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) {
} // namespace node

NODE_MODULE_CONTEXT_AWARE_BUILTIN(async_wrap, node::AsyncWrap::Initialize)


// Only legacy public API below this line.

namespace node {

MaybeLocal<Value> MakeCallback(Isolate* isolate,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these not in node.cc?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No particular reason, except maybe that it kind of belongs to the rest of the legacy code here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All MakeCallback functions are in node.cc including the legacy ones. But since this won't land in master I don't care that much.

Local<Object> recv,
Local<Function> callback,
int argc,
Local<Value>* argv,
async_id asyncId,
async_id triggerAsyncId) {
return MakeCallback(isolate, recv, callback, argc, argv,
{asyncId, triggerAsyncId});
}

MaybeLocal<Value> MakeCallback(Isolate* isolate,
Local<Object> recv,
const char* method,
int argc,
Local<Value>* argv,
async_id asyncId,
async_id triggerAsyncId) {
return MakeCallback(isolate, recv, method, argc, argv,
{asyncId, triggerAsyncId});
}

MaybeLocal<Value> MakeCallback(Isolate* isolate,
Local<Object> recv,
Local<String> symbol,
int argc,
Local<Value>* argv,
async_id asyncId,
async_id triggerAsyncId) {
return MakeCallback(isolate, recv, symbol, argc, argv,
{asyncId, triggerAsyncId});
}

// Undo the Node-8.x-only alias from node.h
#undef EmitAsyncInit

async_uid EmitAsyncInit(Isolate* isolate,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be async_id? Not that it really matters.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? I can change it if you like. 😄

Local<Object> resource,
const char* name,
async_id trigger_async_id) {
return EmitAsyncInit__New(isolate,
resource,
name,
trigger_async_id).async_id;
}

} // namespace node
1 change: 1 addition & 0 deletions src/async-wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "base-object.h"
#include "v8.h"
#include "node.h"

#include <stdint.h>

Expand Down
44 changes: 44 additions & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,16 @@ typedef double async_id;
struct async_context {
::node::async_id async_id;
::node::async_id trigger_async_id;

// Legacy, Node 8.x only.
NODE_DEPRECATED("Use async_context directly as returned by EmitAsyncInit()",
operator ::node::async_id() const {
return async_id;
});
};

typedef async_id async_uid; // Legacy, Node 8.x only

/* Registers an additional v8::PromiseHook wrapper. This API exists because V8
* itself supports only a single PromiseHook. */
NODE_EXTERN void AddPromiseHook(v8::Isolate* isolate,
Expand All @@ -544,6 +552,15 @@ NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
NODE_EXTERN NODE_DEPRECATED("Use AsyncHooksGetTriggerAsyncId(isolate)",
async_id AsyncHooksGetTriggerId(v8::Isolate* isolate));

// This is a legacy overload of EmitAsyncInit that has to remain for ABI
// compatibility during Node 8.x. Do not use.
NODE_EXTERN async_uid EmitAsyncInit(v8::Isolate* isolate,
v8::Local<v8::Object> resource,
const char* name,
async_id trigger_async_id);

// From now on EmitAsyncInit always refers to the proper, new version.
#define EmitAsyncInit EmitAsyncInit__New

/* If the native API doesn't inherit from the helper class then the callbacks
* must be triggered manually. This triggers the init() callback. The return
Expand Down Expand Up @@ -593,6 +610,33 @@ v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
v8::Local<v8::Value>* argv,
async_context asyncContext);

// Legacy, Node 8.x only.

NODE_EXTERN
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not deprecate these too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for pointing that out.

v8::Local<v8::Object> recv,
v8::Local<v8::Function> callback,
int argc,
v8::Local<v8::Value>* argv,
async_id asyncId,
async_id triggerAsyncId);
NODE_EXTERN
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
v8::Local<v8::Object> recv,
const char* method,
int argc,
v8::Local<v8::Value>* argv,
async_id asyncId,
async_id triggerAsyncId);
NODE_EXTERN
v8::MaybeLocal<v8::Value> MakeCallback(v8::Isolate* isolate,
v8::Local<v8::Object> recv,
v8::Local<v8::String> symbol,
int argc,
v8::Local<v8::Value>* argv,
async_id asyncId,
async_id triggerAsyncId);

/* Helper class users can optionally inherit from. If
* `AsyncResource::MakeCallback()` is used, then all four callbacks will be
* called automatically. */
Expand Down
8 changes: 8 additions & 0 deletions test/addons/async-hooks-id/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,17 @@ void GetTriggerAsyncId(const FunctionCallbackInfo<Value>& args) {
node::AsyncHooksGetTriggerAsyncId(args.GetIsolate()));
}

void EmitAsyncInit(const FunctionCallbackInfo<Value>& args) {
assert(args[0]->IsObject());
node::async_uid uid =
node::EmitAsyncInit(args.GetIsolate(), args[0].As<Object>(), "foobar");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EmitAsyncInit that returns async_id requires 4 parameters, correct? Or is this a test for the async_context casting?

Also, is node::async_uid by purpose?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EmitAsyncInit that returns async_id requires 4 parameters, correct? Or is this a test for the async_context casting?

Yes, the latter. The old one is not really exposed through our API anymore, it’s just the symbol that has to keep being exported so already-compiled libraries can reference it.

Also, is node::async_uid by purpose?

Yes, everywhere else in the tests we use async_id now, so there should be one place where we don’t.

args.GetReturnValue().Set(uid);
}

void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "getExecutionAsyncId", GetExecutionAsyncId);
NODE_SET_METHOD(exports, "getTriggerAsyncId", GetTriggerAsyncId);
NODE_SET_METHOD(exports, "emitAsyncInit", EmitAsyncInit);
}

} // namespace
Expand Down
3 changes: 3 additions & 0 deletions test/addons/async-hooks-id/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ assert.strictEqual(
binding.getTriggerAsyncId(),
async_hooks.triggerAsyncId()
);
assert.strictEqual(
typeof binding.emitAsyncInit({}), 'number'
);

process.nextTick(common.mustCall(function() {
assert.strictEqual(
Expand Down