Skip to content

Instantly share code, notes, and snippets.

@tjfontaine
Created February 3, 2014 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjfontaine/8794830 to your computer and use it in GitHub Desktop.
Save tjfontaine/8794830 to your computer and use it in GitHub Desktop.
From 74a81f7588f86b66e277ea70724d17b583efc7d4 Mon Sep 17 00:00:00 2001
From: Timothy J Fontaine <tjfontaine@gmail.com>
Date: Sun, 19 Jan 2014 11:41:25 -0800
Subject: [PATCH] asyncListener: adapt to tracing interface
---
lib/tracing.js | 174 +++++++++++++++++++++++++++++++++++++++++++++++
src/async-wrap-inl.h | 92 +++++++++++++++++++++----
src/async-wrap.h | 77 +++++++++++++++++++--
src/cares_wrap.cc | 24 +++++--
src/env-inl.h | 17 +++++
src/env.h | 8 +++
src/fs_event_wrap.cc | 13 +++-
src/handle_wrap.cc | 7 +-
src/handle_wrap.h | 3 +-
src/node.cc | 7 +-
src/node.js | 7 +-
src/node_crypto.cc | 45 +++++++++---
src/node_crypto.h | 4 +-
src/node_dtrace.cc | 5 +-
src/node_file.cc | 10 ++-
src/node_stat_watcher.cc | 12 ++--
src/node_zlib.cc | 15 ++--
src/pipe_wrap.cc | 26 +++++--
src/process_wrap.cc | 13 +++-
src/req_wrap.h | 4 +-
src/signal_wrap.cc | 13 +++-
src/stream_wrap.cc | 30 ++++++--
src/stream_wrap.h | 9 +--
src/tcp_wrap.cc | 20 ++++--
src/timer_wrap.cc | 10 ++-
src/tls_wrap.cc | 20 ++++--
src/tty_wrap.cc | 6 +-
src/udp_wrap.cc | 25 +++++--
28 files changed, 591 insertions(+), 105 deletions(-)
diff --git a/lib/tracing.js b/lib/tracing.js
index 057e083..abb4b82 100644
--- a/lib/tracing.js
+++ b/lib/tracing.js
@@ -199,12 +199,106 @@ exports.getProvider = function(name) {
return modules[name];
};
+var asyncProviderMap = {
+ 'PROVIDER_UNKNOWN': 1 << 0,
+ 'PROVIDER_TCPWRAP': 1 << 1,
+ 'PROVIDER_CARES': 1 << 2,
+ 'PROVIDER_QUEUE_WORK': 1 << 3,
+ 'PROVIDER_FSWRAP': 1 << 4,
+ 'PROVIDER_SHUTDOWN': 1 << 5,
+ 'PROVIDER_WRITEWRAP': 1 << 6,
+ 'PROVIDER_PIPEWRAP': 1 << 7,
+ 'PROVIDER_UDPWRAP': 1 << 8,
+ 'PROVIDER_CRYPTO': 1 << 9,
+ 'PROVIDER_FSEVENT': 1 << 10,
+ 'PROVIDER_ZLIB': 1 << 11,
+ 'PROVIDER_TLSWRAP': 1 << 12,
+ 'PROVIDER_SIGNAL': 1 << 13,
+ 'PROVIDER_TIMER': 1 << 14,
+ 'PROVIDER_PROCESS': 1 << 15,
+ 'PROVIDER_TTYWRAP': 1 << 16,
+};
+
+var asyncProbeMap = {
+ 'PROBE_UNKNOWN': 1 << 1,
+ 'PROBE_ON_CONNECTION': 1 << 2,
+ 'PROBE_AFTER_CONNECTION': 1 << 3,
+ 'PROBE_ON_READ': 1 << 4,
+ 'PROBE_ON_WRITE': 1 << 5,
+ 'PROBE_CHANGE': 1 << 6,
+ 'PROBE_PARSE_ERROR': 1 << 7,
+ 'PROBE_LOOKUP_DONE': 1 << 8,
+ 'PROBE_CLOSE': 1 << 9,
+ /* TODO(tjfontaine) remove add more specific */
+ 'PROBE_FS_GENERIC': 1 << 10,
+ 'PROBE_STOP': 1 << 11,
+ 'PROBE_AFTER_SHUTDOWN': 1 << 12,
+ 'PROBE_TIMEOUT': 1 << 13,
+ 'PROBE_EXIT': 1 << 14,
+ 'PROBE_HELLO': 1 << 15,
+ 'PROBE_SNI': 1 << 16,
+ 'PROBE_WORK_DONE': 1 << 17,
+ 'PROBE_ERROR': 1 << 18,
+};
+
+var asyncEventMap = {
+ 'EVENT_CREATE': 1 << 1,
+ 'EVENT_BEFORE': 1 << 2,
+ 'EVENT_AFTER': 1 << 3,
+ 'EVENT_ERROR': 1 << 4,
+};
+
+function revMap(map) {
+ var wildcard = 0;
+ Object.keys(map).forEach(function(key) {
+ var val = map[key];
+ map[val] = key;
+ wildcard |= val;
+ });
+ map['*'] = wildcard;
+ map[wildcard] = '*';
+};
+
+revMap(asyncProviderMap);
+revMap(asyncProbeMap);
+revMap(asyncEventMap);
+
exports.on = function(module, probe, cb) {
var listenerModule = listenerCache[module] = listenerCache[module] || {};
var listenerCallbacks = listenerModule[probe] = listenerModule[probe] || {};
listenerCallbacks[cb] = cb;
};
+var asyncStateReadable = {};
+
+exports.onAsync = function(provider, module, ev, cb) {
+ if (!asyncProviderMap[provider] && provider != '*')
+ return;
+
+ if (!asyncProbeMap[module] && module != '*')
+ return;
+
+ if (!util.isFunction(cb)) {
+ cb = ev;
+ ev = '*';
+ }
+
+ var alProvider = asyncStateReadable[provider] = asyncStateReadable[provider] || {};
+ var alProbe = alProvider[module] = alProvider[module] || {};
+ var alEvent = alProbe[ev] = alProbe[ev] || { count: 0, listeners: {}};
+
+ var listeners = alEvent.listeners;
+
+ if (!listeners[cb]) {
+ alEvent.count += 1;
+ listeners[cb] = cb;
+ }
+
+ setALProviders(asyncProviderMap[provider]);
+ setALProbes(asyncProbeMap[module]);
+ setALEvents(asyncEventMap[ev]);
+};
+
exports.removeListener = function(module, probe, cb) {
var listenerModule = listenerCache[module];
@@ -214,6 +308,86 @@ exports.removeListener = function(module, probe, cb) {
delete listenerCache[probe];
};
+var asyncState;
+
+function getALProviders() {
+ return asyncState.readUInt32LE(0);
+}
+
+function setALProviders(mask) {
+ var state = getALProviders() | mask;
+ asyncState.writeUInt32LE(state, 0);
+}
+
+function getALProbes() {
+ return asyncState.readUInt32LE(4);
+}
+
+function setALProbes(mask) {
+ var state = getALProbes() | mask;
+ asyncState.writeUInt32LE(state, 4);
+}
+
+function getALEvents() {
+ return asyncState.readUInt32LE(8);
+}
+
+function setALEvents(mask) {
+ var state = getALEvents() | mask;
+ asyncState.writeUInt32LE(state, 8);
+}
+
+exports.__alTrampoline = function(state) {
+ asyncState = state;
+
+ return asyncFire;
+};
+
+function asyncFire(provider, type, ev, context, args) {
+ baseType = asyncProbeMap[type];
+ baseEv = asyncEventMap[ev];
+ baseProvider = asyncProviderMap[provider];
+
+ var listeners = [];
+
+ //TODO(tjfontaine) consolidate with getListeners
+ Object.keys(asyncStateReadable).forEach(function(stateProvider) {
+ if (stateProvider !== baseProvider && stateProvider !== '*') {
+ process._rawDebug(stateProvider, baseProvider);
+ return;
+ }
+
+ var stateProbes = asyncStateReadable[stateProvider];
+
+ Object.keys(stateProbes).forEach(function(stateProbe) {
+ if (stateProbe !== baseType && stateProbe !== '*') {
+ process._rawDebug(stateProbe, baseType);
+ return;
+ }
+
+ var probe = stateProbes[stateProbe];
+
+ Object.keys(probe).forEach(function(eventKey) {
+ if (eventKey != baseEv && eventKey !== '*') {
+ process._rawDebug(eventKey, baseEvent);
+ return;
+ }
+
+ var event = probe[eventKey];
+
+ Object.keys(event.listeners).forEach(function(key) {
+ listeners.push(event.listeners[key]);
+ });
+ });
+ });
+ });
+
+ for (var i = 0; i < listeners.length; i++) {
+ var f = listeners[i];
+ f(context, args, baseProvider, baseType, baseEv);
+ }
+};
+
var httpProvider = new StaticProvider('http');
var netProvider = new StaticProvider('net');
diff --git a/src/async-wrap-inl.h b/src/async-wrap-inl.h
index aad1dcb..15cf96d 100644
--- a/src/async-wrap-inl.h
+++ b/src/async-wrap-inl.h
@@ -35,18 +35,28 @@
namespace node {
-inline AsyncWrap::AsyncWrap(Environment* env, v8::Handle<v8::Object> object)
+inline AsyncWrap::AsyncWrap(Environment* env,
+ v8::Handle<v8::Object> object,
+ AsyncProviderType provider)
: BaseObject(env, object),
- async_flags_(NO_OPTIONS) {
- if (!env->has_async_listener())
+ async_flags_(NO_OPTIONS),
+ provider_(provider) {
+}
+
+
+inline void AsyncWrap::Create() {
+ v8::Local<v8::Value> val = object().As<v8::Value>();
+
+ Fire(val, PROBE_UNKNOWN, EVENT_CREATE);
+
+ if (!env()->has_async_listener())
return;
// TODO(trevnorris): Do we really need to TryCatch this call?
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
- v8::Local<v8::Value> val = object.As<v8::Value>();
- env->async_listener_run_function()->Call(env->process_object(), 1, &val);
+ env()->async_listener_run_function()->Call(env()->process_object(), 1, &val);
if (!try_catch.HasCaught())
async_flags_ |= HAS_ASYNC_LISTENER;
@@ -71,7 +81,8 @@ inline bool AsyncWrap::has_async_listener() {
inline v8::Handle<v8::Value> AsyncWrap::MakeDomainCallback(
const v8::Handle<v8::Function> cb,
int argc,
- v8::Handle<v8::Value>* argv) {
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type) {
assert(env()->context() == env()->isolate()->GetCurrentContext());
v8::Local<v8::Object> context = object();
@@ -156,12 +167,59 @@ inline v8::Handle<v8::Value> AsyncWrap::MakeDomainCallback(
}
+void AsyncWrap::Fire(v8::Local<v8::Value> val,
+ uint32_t probe,
+ uint32_t event,
+ int argc,
+ v8::Handle<v8::Value>* argv) {
+ v8::HandleScope scope(env()->isolate());
+
+ /* Check if we have set the mask for this provider or probe, bail if not */
+
+ if ((provider_ & env()->get_al_providers()) == 0) {
+ return;
+ }
+
+ if ((probe & env()->get_al_probes()) == 0) {
+ return;
+ }
+
+ if ((event & env()->get_al_events()) == 0) {
+ return;
+ }
+
+ v8::Local<v8::Value> args[5];
+ args[0] = v8::Integer::NewFromUnsigned(provider_, env()->isolate());
+ args[1] = v8::Integer::NewFromUnsigned(probe, env()->isolate());
+ args[2] = v8::Integer::NewFromUnsigned(event, env()->isolate());
+ args[3] = val;
+
+ /* TODO(tjfontaine) -- would be nice to *not* use an Array for this.
+ * Not the most ideal situation, this results in one new object and a shallow
+ * clone of the arguments being used with the MakeCallback, it's reasonably
+ * safe, and expense wise is only cheaper if we could reuse the array in
+ * place.
+ */
+ if (argc > 0) {
+ v8::Local<v8::Array> arr = v8::Array::New(argc);
+ for (int i = 0; i < argc; i++)
+ arr->Set(i, argv[i]);
+ args[4] = arr;
+ } else {
+ args[4] = Undefined(env()->isolate());
+ }
+
+ env()->tracing_trampoline_function()->Call(v8::Null(), 5, args);
+}
+
+
inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
const v8::Handle<v8::Function> cb,
int argc,
- v8::Handle<v8::Value>* argv) {
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type) {
if (env()->using_domains())
- return MakeDomainCallback(cb, argc, argv);
+ return MakeDomainCallback(cb, argc, argv, type);
assert(env()->context() == env()->isolate()->GetCurrentContext());
@@ -171,8 +229,11 @@ inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
+ v8::Local<v8::Value> val = context.As<v8::Value>();
+
+ Fire(val, type, EVENT_BEFORE, argc, argv);
+
if (has_async_listener()) {
- v8::Local<v8::Value> val = context.As<v8::Value>();
env()->async_listener_load_function()->Call(process, 1, &val);
if (try_catch.HasCaught())
@@ -185,8 +246,9 @@ inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
return Undefined(env()->isolate());
}
+ Fire(val, type, EVENT_AFTER, argc, argv);
+
if (has_async_listener()) {
- v8::Local<v8::Value> val = context.As<v8::Value>();
env()->async_listener_unload_function()->Call(process, 1, &val);
if (try_catch.HasCaught())
@@ -222,24 +284,26 @@ inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
const v8::Handle<v8::String> symbol,
int argc,
- v8::Handle<v8::Value>* argv) {
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type) {
v8::Local<v8::Value> cb_v = object()->Get(symbol);
v8::Local<v8::Function> cb = cb_v.As<v8::Function>();
assert(cb->IsFunction());
- return MakeCallback(cb, argc, argv);
+ return MakeCallback(cb, argc, argv, type);
}
inline v8::Handle<v8::Value> AsyncWrap::MakeCallback(
uint32_t index,
int argc,
- v8::Handle<v8::Value>* argv) {
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type) {
v8::Local<v8::Value> cb_v = object()->Get(index);
v8::Local<v8::Function> cb = cb_v.As<v8::Function>();
assert(cb->IsFunction());
- return MakeCallback(cb, argc, argv);
+ return MakeCallback(cb, argc, argv, type);
}
} // namespace node
diff --git a/src/async-wrap.h b/src/async-wrap.h
index a58031b..c3f3795 100644
--- a/src/async-wrap.h
+++ b/src/async-wrap.h
@@ -28,6 +28,55 @@
namespace node {
+enum AsyncProviderType {
+ PROVIDER_UNKNOWN = 1 << 0,
+ PROVIDER_TCPWRAP = 1 << 1,
+ PROVIDER_CARES = 1 << 2,
+ PROVIDER_QUEUE_WORK = 1 << 3,
+ PROVIDER_FSWRAP = 1 << 4,
+ PROVIDER_SHUTDOWN = 1 << 5,
+ PROVIDER_WRITEWRAP = 1 << 6,
+ PROVIDER_PIPEWRAP = 1 << 7,
+ PROVIDER_UDPWRAP = 1 << 8,
+ PROVIDER_CRYPTO = 1 << 9,
+ PROVIDER_FSEVENT = 1 << 10,
+ PROVIDER_ZLIB = 1 << 11,
+ PROVIDER_TLSWRAP = 1 << 12,
+ PROVIDER_SIGNAL = 1 << 13,
+ PROVIDER_TIMER = 1 << 14,
+ PROVIDER_PROCESS = 1 << 15,
+ PROVIDER_TTYWRAP = 1 << 16,
+};
+
+enum AsyncProbeEvent {
+ EVENT_CREATE = 1 << 1,
+ EVENT_BEFORE = 1 << 2,
+ EVENT_AFTER = 1 << 3,
+ EVENT_ERROR = 1 << 4,
+};
+
+enum AsyncProbeType {
+ PROBE_UNKNOWN = 1 << 1,
+ PROBE_ON_CONNECTION = 1 << 2,
+ PROBE_AFTER_CONNECTION = 1 << 3,
+ PROBE_ON_READ = 1 << 4,
+ PROBE_ON_WRITE = 1 << 5,
+ PROBE_CHANGE = 1 << 6,
+ PROBE_PARSE_ERROR = 1 << 7,
+ PROBE_LOOKUP_DONE = 1 << 8,
+ PROBE_CLOSE = 1 << 9,
+ /* TODO(tjfontaine) remove add more specific */
+ PROBE_FS_GENERIC = 1 << 10,
+ PROBE_STOP = 1 << 11,
+ PROBE_AFTER_SHUTDOWN = 1 << 12,
+ PROBE_TIMEOUT = 1 << 13,
+ PROBE_EXIT = 1 << 14,
+ PROBE_HELLO = 1 << 15,
+ PROBE_SNI = 1 << 16,
+ PROBE_WORK_DONE = 1 << 17,
+ PROBE_ERROR = 1 << 18,
+};
+
class AsyncWrap : public BaseObject {
public:
enum AsyncFlags {
@@ -35,10 +84,16 @@ class AsyncWrap : public BaseObject {
HAS_ASYNC_LISTENER = 1
};
- inline AsyncWrap(Environment* env, v8::Handle<v8::Object> object);
+ inline AsyncWrap(Environment* env,
+ v8::Handle<v8::Object> object,
+ AsyncProviderType provider);
inline ~AsyncWrap();
+ inline void Create();
+
+ static inline void AddMethods(v8::Handle<v8::FunctionTemplate> t);
+
inline uint32_t async_flags() const;
inline bool has_async_listener();
@@ -46,25 +101,37 @@ class AsyncWrap : public BaseObject {
// Only call these within a valid HandleScope.
inline v8::Handle<v8::Value> MakeCallback(const v8::Handle<v8::Function> cb,
int argc,
- v8::Handle<v8::Value>* argv);
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type);
inline v8::Handle<v8::Value> MakeCallback(const v8::Handle<v8::String> symbol,
int argc,
- v8::Handle<v8::Value>* argv);
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type);
inline v8::Handle<v8::Value> MakeCallback(uint32_t index,
int argc,
- v8::Handle<v8::Value>* argv);
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type);
private:
inline AsyncWrap();
+ inline void Fire(const v8::Local<v8::Value> val,
+ uint32_t probe,
+ uint32_t event,
+ int argc = 0,
+ v8::Handle<v8::Value>* argv = NULL);
+
// TODO(trevnorris): BURN IN FIRE! Remove this as soon as a suitable
// replacement is committed.
inline v8::Handle<v8::Value> MakeDomainCallback(
const v8::Handle<v8::Function> cb,
int argc,
- v8::Handle<v8::Value>* argv);
+ v8::Handle<v8::Value>* argv,
+ AsyncProbeType type);
uint32_t async_flags_;
+
+ AsyncProviderType provider_;
};
} // namespace node
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index bc59513..5d02a37 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -61,7 +61,7 @@ using v8::Object;
using v8::String;
using v8::Value;
-typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;
+typedef class ReqWrap<uv_getaddrinfo_t, PROVIDER_CARES> GetAddrInfoReqWrap;
static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) {
@@ -224,7 +224,7 @@ static Local<Array> HostentToNames(struct hostent* host) {
class QueryWrap : public AsyncWrap {
public:
QueryWrap(Environment* env, Local<Object> req_wrap_obj)
- : AsyncWrap(env, req_wrap_obj) {
+ : AsyncWrap(env, req_wrap_obj, PROVIDER_CARES) {
}
virtual ~QueryWrap() {
@@ -281,7 +281,10 @@ class QueryWrap : public AsyncWrap {
Integer::New(0, env()->isolate()),
answer
};
- MakeCallback(env()->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ MakeCallback(env()->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_LOOKUP_DONE);
}
void CallOnComplete(Local<Value> answer, Local<Value> family) {
@@ -292,7 +295,10 @@ class QueryWrap : public AsyncWrap {
answer,
family
};
- MakeCallback(env()->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ MakeCallback(env()->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_LOOKUP_DONE);
}
void ParseError(int status) {
@@ -334,7 +340,7 @@ class QueryWrap : public AsyncWrap {
arg = FIXED_ONE_BYTE_STRING(env()->isolate(), "UNKNOWN_ARES_ERROR");
break;
}
- MakeCallback(env()->oncomplete_string(), 1, &arg);
+ MakeCallback(env()->oncomplete_string(), 1, &arg, PROBE_PARSE_ERROR);
}
// Subclasses should implement the appropriate Parse method.
@@ -847,6 +853,7 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
Local<Object> req_wrap_obj = args[0].As<Object>();
Local<String> string = args[1].As<String>();
Wrap* wrap = new Wrap(env, req_wrap_obj);
+ wrap->Create();
String::Utf8Value name(string);
int err = wrap->Send(*name);
@@ -859,6 +866,7 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
GetAddrInfoReqWrap* req_wrap = static_cast<GetAddrInfoReqWrap*>(req->data);
+ req_wrap->Create();
Environment* env = req_wrap->env();
HandleScope handle_scope(env->isolate());
@@ -949,7 +957,10 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
uv_freeaddrinfo(res);
// Make the callback into JavaScript
- req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_LOOKUP_DONE);
delete req_wrap;
}
@@ -998,6 +1009,7 @@ static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
}
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
+ req_wrap->Create();
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
diff --git a/src/env-inl.h b/src/env-inl.h
index 63f5a94..77d52e1 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -220,6 +220,7 @@ inline Environment::Environment(v8::Local<v8::Context> context)
isolate_data_(IsolateData::GetOrCreate(context->GetIsolate())),
using_smalloc_alloc_cb_(false),
using_domains_(false),
+ async_state_(NULL),
context_(context->GetIsolate(), context) {
// We'll be creating new objects so make sure we've entered the context.
v8::HandleScope handle_scope(isolate());
@@ -342,6 +343,22 @@ inline ares_task_list* Environment::cares_task_list() {
return &cares_task_list_;
}
+inline void Environment::set_async_state(void* data) {
+ async_state_ = reinterpret_cast<uint32_t*>(data);
+}
+
+inline uint32_t Environment::get_al_providers() {
+ return async_state_[0];
+}
+
+inline uint32_t Environment::get_al_probes() {
+ return async_state_[1];
+}
+
+inline uint32_t Environment::get_al_events() {
+ return async_state_[2];
+}
+
inline Environment::IsolateData* Environment::isolate_data() const {
return isolate_data_;
}
diff --git a/src/env.h b/src/env.h
index 2bafcd1..3eb5cd5 100644
--- a/src/env.h
+++ b/src/env.h
@@ -166,6 +166,7 @@ namespace node {
V(stats_constructor_function, v8::Function) \
V(tcp_constructor_template, v8::FunctionTemplate) \
V(tick_callback_function, v8::Function) \
+ V(tracing_trampoline_function, v8::Function) \
V(tls_wrap_constructor_function, v8::Function) \
V(tty_constructor_template, v8::FunctionTemplate) \
V(udp_constructor_function, v8::Function) \
@@ -286,6 +287,11 @@ class Environment {
inline DomainFlag* domain_flag();
inline TickInfo* tick_info();
+ inline void set_async_state(void* data);
+ inline uint32_t get_al_providers();
+ inline uint32_t get_al_probes();
+ inline uint32_t get_al_events();
+
static inline Environment* from_cares_timer_handle(uv_timer_t* handle);
inline uv_timer_t* cares_timer_handle();
inline ares_channel cares_channel();
@@ -340,6 +346,8 @@ class Environment {
bool using_domains_;
QUEUE gc_tracker_queue_;
+ uint32_t* async_state_;
+
#define V(PropertyName, TypeName) \
v8::Persistent<TypeName> PropertyName ## _;
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc
index 3a3559c..a6abd59 100644
--- a/src/fs_event_wrap.cc
+++ b/src/fs_event_wrap.cc
@@ -65,7 +65,10 @@ class FSEventWrap: public HandleWrap {
FSEventWrap::FSEventWrap(Environment* env, Handle<Object> object)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ : HandleWrap(env,
+ object,
+ reinterpret_cast<uv_handle_t*>(&handle_),
+ PROVIDER_FSEVENT) {
initialized_ = false;
}
@@ -93,7 +96,8 @@ void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new FSEventWrap(env, args.This());
+ FSEventWrap *w = new FSEventWrap(env, args.This());
+ w->Create();
}
@@ -175,7 +179,10 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
argv[2] = OneByteString(node_isolate, filename);
}
- wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(env->onchange_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_CHANGE);
}
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index 0a7f7d2..710077b 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -90,8 +90,9 @@ void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
HandleWrap::HandleWrap(Environment* env,
Handle<Object> object,
- uv_handle_t* handle)
- : AsyncWrap(env, object),
+ uv_handle_t* handle,
+ AsyncProviderType provider)
+ : AsyncWrap(env, object, provider),
flags_(0),
handle__(handle) {
handle__->data = this;
@@ -124,7 +125,7 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
Local<Object> object = wrap->object();
if (wrap->flags_ & kCloseCallback) {
- wrap->MakeCallback(env->close_string(), 0, NULL);
+ wrap->MakeCallback(env->close_string(), 0, NULL, PROBE_CLOSE);
}
object->SetAlignedPointerInInternalField(0, NULL);
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
index 47cc44f..70820e5 100644
--- a/src/handle_wrap.h
+++ b/src/handle_wrap.h
@@ -62,7 +62,8 @@ class HandleWrap : public AsyncWrap {
protected:
HandleWrap(Environment* env,
v8::Handle<v8::Object> object,
- uv_handle_t* handle);
+ uv_handle_t* handle,
+ AsyncProviderType provider);
virtual ~HandleWrap();
private:
diff --git a/src/node.cc b/src/node.cc
index b32ea37..9687ae4 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -862,6 +862,10 @@ void SetupAsyncListener(const FunctionCallbackInfo<Value>& args) {
env->set_async_listener_load_function(args[2].As<Function>());
env->set_async_listener_unload_function(args[3].As<Function>());
+ env->set_tracing_trampoline_function(args[4].As<Function>());
+
+ env->set_async_state(Buffer::Data(args[5]));
+
Local<Object> async_listener_flag_obj = args[0].As<Object>();
Environment::AsyncListener* async_listener = env->async_listener();
async_listener_flag_obj->SetIndexedPropertiesToExternalArrayData(
@@ -1415,6 +1419,7 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
return scope.Close(result);
}
+typedef ReqWrap<uv_req_t, PROVIDER_QUEUE_WORK> ReqWrapWork;
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
@@ -1424,7 +1429,7 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
int i = 0;
QUEUE_FOREACH(q, &req_wrap_queue) {
- ReqWrap<uv_req_t>* w = CONTAINER_OF(q, ReqWrap<uv_req_t>, req_wrap_queue_);
+ ReqWrapWork* w = CONTAINER_OF(q, ReqWrapWork, req_wrap_queue_);
if (w->persistent().IsEmpty())
continue;
ary->Set(i++, w->object());
diff --git a/src/node.js b/src/node.js
index 0b598c6..11ac825 100644
--- a/src/node.js
+++ b/src/node.js
@@ -306,11 +306,16 @@
process.addAsyncListener = addAsyncListener;
process.removeAsyncListener = removeAsyncListener;
+ var asyncState = new Buffer(12).fill(0);
+ var tracing = NativeModule.require('tracing').__alTrampoline(asyncState);
+
// Setup shared objects/callbacks with native layer.
process._setupAsyncListener(asyncFlags,
runAsyncQueue,
loadAsyncQueue,
- unloadAsyncQueue);
+ unloadAsyncQueue,
+ tracing,
+ asyncState);
// Load the currently executing context as the current context, and
// create a new asyncQueue that can receive any added queue items
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 987e2cf..f373035 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -928,7 +928,10 @@ int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
reinterpret_cast<char*>(sess->session_id),
sess->session_id_length);
Local<Value> argv[] = { session, buff };
- w->MakeCallback(env->onnewsession_string(), ARRAY_SIZE(argv), argv);
+ w->MakeCallback(env->onnewsession_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_CONNECTION);
return 0;
}
@@ -959,7 +962,10 @@ void SSLWrap<Base>::OnClientHello(void* arg,
hello_obj->Set(env->tls_ticket_string(), Boolean::New(hello.has_ticket()));
Local<Value> argv[] = { hello_obj };
- w->MakeCallback(env->onclienthello_string(), ARRAY_SIZE(argv), argv);
+ w->MakeCallback(env->onclienthello_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_HELLO);
}
@@ -1730,7 +1736,10 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
conn->sniContext_.Dispose();
Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
- Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
+ Local<Value> ret = conn->MakeCallback(env->onselect_string(),
+ 1,
+ &arg,
+ PROBE_SNI);
// If ret is SecureContext
Local<FunctionTemplate> secure_context_constructor_template =
@@ -1765,6 +1774,7 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
SSLWrap<Connection>::Kind kind =
is_server ? SSLWrap<Connection>::kServer : SSLWrap<Connection>::kClient;
Connection* conn = new Connection(env, args.This(), sc, kind);
+ conn->Create();
conn->ssl_ = SSL_new(sc->ctx_);
conn->bio_read_ = NodeBIO::New();
conn->bio_write_ = NodeBIO::New();
@@ -1835,11 +1845,17 @@ void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
Context::Scope context_scope(env->context());
if (where & SSL_CB_HANDSHAKE_START) {
- conn->MakeCallback(env->onhandshakestart_string(), 0, NULL);
+ conn->MakeCallback(env->onhandshakestart_string(),
+ 0,
+ NULL,
+ PROBE_SNI);
}
if (where & SSL_CB_HANDSHAKE_DONE) {
- conn->MakeCallback(env->onhandshakedone_string(), 0, NULL);
+ conn->MakeCallback(env->onhandshakedone_string(),
+ 0,
+ NULL,
+ PROBE_SNI);
}
}
@@ -3478,7 +3494,7 @@ class PBKDF2Request : public AsyncWrap {
char* salt,
ssize_t iter,
ssize_t keylen)
- : AsyncWrap(env, object),
+ : AsyncWrap(env, object, PROVIDER_CRYPTO),
digest_(digest),
error_(0),
passlen_(passlen),
@@ -3607,7 +3623,10 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
Context::Scope context_scope(env->context());
Local<Value> argv[2];
EIO_PBKDF2After(req, argv);
- req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
+ req->MakeCallback(env->ondone_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_WORK_DONE);
req->release();
delete req;
}
@@ -3708,6 +3727,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
salt,
iter,
keylen);
+ req->Create();
if (args[5]->IsFunction()) {
obj->Set(env->ondone_string(), args[5]);
@@ -3740,7 +3760,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
class RandomBytesRequest : public AsyncWrap {
public:
RandomBytesRequest(Environment* env, Local<Object> object, size_t size)
- : AsyncWrap(env, object),
+ : AsyncWrap(env, object, PROVIDER_CRYPTO),
error_(0),
size_(size),
data_(static_cast<char*>(malloc(size))) {
@@ -3849,7 +3869,10 @@ void RandomBytesAfter(uv_work_t* work_req, int status) {
Context::Scope context_scope(env->context());
Local<Value> argv[2];
RandomBytesCheck(req, argv);
- req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
+ req->MakeCallback(env->ondone_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_WORK_DONE);
delete req;
}
@@ -3872,6 +3895,7 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
Local<Object> obj = Object::New();
RandomBytesRequest* req = new RandomBytesRequest(env, obj, size);
+ req->Create();
if (args[1]->IsFunction()) {
obj->Set(FIXED_ONE_BYTE_STRING(args.GetIsolate(), "ondone"), args[1]);
@@ -3971,7 +3995,8 @@ void Certificate::Initialize(Handle<Object> target) {
void Certificate::New(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new Certificate(env, args.This());
+ Certificate *c = new Certificate(env, args.This());
+ c->Create();
}
diff --git a/src/node_crypto.h b/src/node_crypto.h
index aa670db..004e672 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -296,7 +296,7 @@ class Connection : public SSLWrap<Connection>, public AsyncWrap {
SecureContext* sc,
SSLWrap<Connection>::Kind kind)
: SSLWrap<Connection>(env, sc, kind),
- AsyncWrap(env, wrap),
+ AsyncWrap(env, wrap, PROVIDER_CRYPTO),
bio_read_(NULL),
bio_write_(NULL),
hello_offset_(0) {
@@ -582,7 +582,7 @@ class Certificate : public AsyncWrap {
static void ExportChallenge(const v8::FunctionCallbackInfo<v8::Value>& args);
Certificate(Environment* env, v8::Local<v8::Object> wrap)
- : AsyncWrap(env, wrap) {
+ : AsyncWrap(env, wrap, PROVIDER_CRYPTO) {
MakeWeak<Certificate>(this);
}
};
diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc
index 3978a73..065b915 100644
--- a/src/node_dtrace.cc
+++ b/src/node_dtrace.cc
@@ -238,7 +238,8 @@ static int dtrace_gc_done(GCType type, GCCallbackFlags flags) {
void InitDTrace(Handle<Object> target,
Handle<Value> unused,
- Handle<v8::Context> context) {
+ Handle<v8::Context> context,
+ void* priv) {
HandleScope scope(node_isolate);
#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
@@ -280,4 +281,4 @@ void InitDTrace(Handle<Object> target,
}
-NODE_MODULE_CONTEXT_AWARE(node_dtrace, node::InitDTrace)
+NODE_MODULE_CONTEXT_AWARE_BUILTIN(dtrace, node::InitDTrace)
diff --git a/src/node_file.cc b/src/node_file.cc
index 109eea8..beb0c7f 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -64,13 +64,13 @@ using v8::Value;
#define THROW_BAD_ARGS TYPE_ERROR("Bad argument")
-class FSReqWrap: public ReqWrap<uv_fs_t> {
+class FSReqWrap: public ReqWrap<uv_fs_t, PROVIDER_FSWRAP> {
public:
void* operator new(size_t size) { return new char[size]; }
void* operator new(size_t size, char* storage) { return storage; }
FSReqWrap(Environment* env, const char* syscall, char* data = NULL)
- : ReqWrap<uv_fs_t>(env, Object::New()),
+ : ReqWrap<uv_fs_t, PROVIDER_FSWRAP>(env, Object::New()),
syscall_(syscall),
data_(data),
dest_len_(0) {
@@ -231,7 +231,10 @@ static void After(uv_fs_t *req) {
}
}
- req_wrap->MakeCallback(env->oncomplete_string(), argc, argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ argc,
+ argv,
+ PROBE_FS_GENERIC);
uv_fs_req_cleanup(&req_wrap->req_);
delete req_wrap;
@@ -809,6 +812,7 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
}
FSReqWrap* req_wrap = new FSReqWrap(env, "write", must_free ? buf : NULL);
+ req_wrap->Create();
int err = uv_fs_write(env->event_loop(),
&req_wrap->req_,
fd,
diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc
index e71ca43..7e84b73 100644
--- a/src/node_stat_watcher.cc
+++ b/src/node_stat_watcher.cc
@@ -66,7 +66,7 @@ static void Delete(uv_handle_t* handle) {
StatWatcher::StatWatcher(Environment* env, Local<Object> wrap)
- : AsyncWrap(env, wrap),
+ : AsyncWrap(env, wrap, PROVIDER_FSEVENT),
watcher_(new uv_fs_poll_t) {
MakeWeak<StatWatcher>(this);
uv_fs_poll_init(env->event_loop(), watcher_);
@@ -94,7 +94,10 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
BuildStatsObject(env, prev),
Integer::New(status, node_isolate)
};
- wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(env->onchange_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_FS_GENERIC);
}
@@ -102,7 +105,8 @@ void StatWatcher::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new StatWatcher(env, args.This());
+ StatWatcher *s = new StatWatcher(env, args.This());
+ s->Create();
}
@@ -127,7 +131,7 @@ void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) {
Environment* env = wrap->env();
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
- wrap->MakeCallback(env->onstop_string(), 0, NULL);
+ wrap->MakeCallback(env->onstop_string(), 0, NULL, PROBE_STOP);
wrap->Stop();
}
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index 8a2125f..1798d44 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -74,7 +74,7 @@ class ZCtx : public AsyncWrap {
public:
ZCtx(Environment* env, Local<Object> wrap, node_zlib_mode mode)
- : AsyncWrap(env, wrap),
+ : AsyncWrap(env, wrap, PROVIDER_ZLIB),
chunk_size_(0),
dictionary_(NULL),
dictionary_len_(0),
@@ -320,7 +320,10 @@ class ZCtx : public AsyncWrap {
// call the write() cb
Local<Value> args[2] = { avail_in, avail_out };
- ctx->MakeCallback(env->callback_string(), ARRAY_SIZE(args), args);
+ ctx->MakeCallback(env->callback_string(),
+ ARRAY_SIZE(args),
+ args,
+ PROBE_ON_WRITE);
ctx->Unref();
}
@@ -340,7 +343,10 @@ class ZCtx : public AsyncWrap {
OneByteString(node_isolate, message),
Number::New(ctx->err_)
};
- ctx->MakeCallback(env->onerror_string(), ARRAY_SIZE(args), args);
+ ctx->MakeCallback(env->onerror_string(),
+ ARRAY_SIZE(args),
+ args,
+ PROBE_ERROR);
// no hope of rescue.
ctx->write_in_progress_ = false;
@@ -360,7 +366,8 @@ class ZCtx : public AsyncWrap {
return ThrowTypeError("Bad argument");
}
- new ZCtx(env, args.This(), mode);
+ ZCtx *z = new ZCtx(env, args.This(), mode);
+ z->Create();
}
// just pull the ints out of the args and call the other Init
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 517d97c..f5a789e 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -50,7 +50,7 @@ using v8::Undefined;
using v8::Value;
// TODO(bnoordhuis) share with TCPWrap?
-typedef class ReqWrap<uv_connect_t> ConnectWrap;
+typedef class ReqWrap<uv_connect_t, PROVIDER_PIPEWRAP> ConnectWrap;
uv_pipe_t* PipeWrap::UVHandle() {
@@ -123,12 +123,16 @@ void PipeWrap::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new PipeWrap(env, args.This(), args[0]->IsTrue());
+ PipeWrap *pw = new PipeWrap(env, args.This(), args[0]->IsTrue());
+ pw->Create();
}
PipeWrap::PipeWrap(Environment* env, Handle<Object> object, bool ipc)
- : StreamWrap(env, object, reinterpret_cast<uv_stream_t*>(&handle_)) {
+ : StreamWrap(env,
+ object,
+ reinterpret_cast<uv_stream_t*>(&handle_),
+ PROVIDER_PIPEWRAP) {
int r = uv_pipe_init(env->event_loop(), &handle_, ipc);
assert(r == 0); // How do we proxy this error up to javascript?
// Suggestion: uv_pipe_init() returns void.
@@ -192,7 +196,10 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
};
if (status != 0) {
- pipe_wrap->MakeCallback(env->onconnection_string(), ARRAY_SIZE(argv), argv);
+ pipe_wrap->MakeCallback(env->onconnection_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_CONNECTION);
return;
}
@@ -208,7 +215,10 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
// Successful accept. Call the onconnection callback in JavaScript land.
argv[1] = client_obj;
- pipe_wrap->MakeCallback(env->onconnection_string(), ARRAY_SIZE(argv), argv);
+ pipe_wrap->MakeCallback(env->onconnection_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_CONNECTION);
}
// TODO(bnoordhuis) Maybe share this with TCPWrap?
@@ -243,7 +253,10 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
Boolean::New(writable)
};
- req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_AFTER_CONNECTION);
delete req_wrap;
}
@@ -276,6 +289,7 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
String::AsciiValue name(args[1]);
ConnectWrap* req_wrap = new ConnectWrap(env, req_wrap_obj);
+ req_wrap->Create();
uv_pipe_connect(&req_wrap->req_,
&wrap->handle_,
*name,
diff --git a/src/process_wrap.cc b/src/process_wrap.cc
index 5592cfe..5373a6f 100644
--- a/src/process_wrap.cc
+++ b/src/process_wrap.cc
@@ -74,11 +74,15 @@ class ProcessWrap : public HandleWrap {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new ProcessWrap(env, args.This());
+ ProcessWrap *pw = new ProcessWrap(env, args.This());
+ pw->Create();
}
ProcessWrap(Environment* env, Handle<Object> object)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&process_)) {
+ : HandleWrap(env,
+ object,
+ reinterpret_cast<uv_handle_t*>(&process_),
+ PROVIDER_PROCESS) {
}
~ProcessWrap() {
@@ -284,7 +288,10 @@ class ProcessWrap : public HandleWrap {
OneByteString(node_isolate, signo_string(term_signal))
};
- wrap->MakeCallback(env->onexit_string(), ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(env->onexit_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_EXIT);
}
uv_process_t process_;
diff --git a/src/req_wrap.h b/src/req_wrap.h
index 043edb2..558ddec 100644
--- a/src/req_wrap.h
+++ b/src/req_wrap.h
@@ -34,11 +34,11 @@ namespace node {
// defined in node.cc
extern QUEUE req_wrap_queue;
-template <typename T>
+template <typename T, AsyncProviderType P>
class ReqWrap : public AsyncWrap {
public:
ReqWrap(Environment* env, v8::Handle<v8::Object> object)
- : AsyncWrap(env, object) {
+ : AsyncWrap(env, object, P) {
if (env->in_domain())
object->Set(env->domain_string(), env->domain_array()->Get(0));
diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc
index 74eb830..c205453 100644
--- a/src/signal_wrap.cc
+++ b/src/signal_wrap.cc
@@ -68,11 +68,15 @@ class SignalWrap : public HandleWrap {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new SignalWrap(env, args.This());
+ SignalWrap *sw = new SignalWrap(env, args.This());
+ sw->Create();
}
SignalWrap(Environment* env, Handle<Object> object)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ : HandleWrap(env,
+ object,
+ reinterpret_cast<uv_handle_t*>(&handle_),
+ PROVIDER_SIGNAL) {
int r = uv_signal_init(env->event_loop(), &handle_);
assert(r == 0);
}
@@ -104,7 +108,10 @@ class SignalWrap : public HandleWrap {
Context::Scope context_scope(env->context());
Local<Value> arg = Integer::New(signum, env->isolate());
- wrap->MakeCallback(env->onsignal_string(), 1, &arg);
+ wrap->MakeCallback(env->onsignal_string(),
+ 1,
+ &arg,
+ PROBE_CHANGE);
}
uv_signal_t handle_;
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index 848abef..2b593e0 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -57,8 +57,9 @@ using v8::Value;
StreamWrap::StreamWrap(Environment* env,
Local<Object> object,
- uv_stream_t* stream)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(stream)),
+ uv_stream_t* stream,
+ AsyncProviderType provider)
+ : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(stream), provider),
stream_(stream),
default_callbacks_(this),
callbacks_(&default_callbacks_) {
@@ -219,6 +220,7 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
// Allocate, or write rest
storage = new char[sizeof(WriteWrap)];
req_wrap = new(storage) WriteWrap(env, req_wrap_obj, wrap);
+ req_wrap->Create();
err = wrap->callbacks()->DoWrite(req_wrap,
bufs,
@@ -290,6 +292,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
uv_buf_t* bufs = &buf;
size_t count = 1;
+ // TODO(tjfontaine) missed by AL because it's no longer Async
err = wrap->callbacks()->TryWrite(&bufs, &count);
// Success
@@ -302,6 +305,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
storage = new char[sizeof(WriteWrap) + storage_size + 15];
req_wrap = new(storage) WriteWrap(env, req_wrap_obj, wrap);
+ req_wrap->Create();
data = reinterpret_cast<char*>(ROUND_UP(
reinterpret_cast<uintptr_t>(storage) + sizeof(WriteWrap), 16));
@@ -413,6 +417,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
char* storage = new char[storage_size];
WriteWrap* req_wrap =
new(storage) WriteWrap(env, req_wrap_obj, wrap);
+ req_wrap->Create();
uint32_t bytes = 0;
size_t offset = sizeof(WriteWrap);
@@ -512,7 +517,10 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) {
if (msg != NULL)
argv[3] = OneByteString(env->isolate(), msg);
- req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_WRITE);
req_wrap->~WriteWrap();
delete[] reinterpret_cast<char*>(req_wrap);
@@ -529,6 +537,7 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
Local<Object> req_wrap_obj = args[0].As<Object>();
ShutdownWrap* req_wrap = new ShutdownWrap(env, req_wrap_obj);
+ req_wrap->Create();
int err = wrap->callbacks()->DoShutdown(req_wrap, AfterShutdown);
req_wrap->Dispatched();
if (err)
@@ -556,7 +565,10 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
req_wrap_obj
};
- req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_AFTER_SHUTDOWN);
delete req_wrap;
}
@@ -673,7 +685,10 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
if (nread < 0) {
if (buf->base != NULL)
free(buf->base);
- wrap()->MakeCallback(env->onread_string(), ARRAY_SIZE(argv), argv);
+ wrap()->MakeCallback(env->onread_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_READ);
return;
}
@@ -702,7 +717,10 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
argv[2] = pending_obj;
}
- wrap()->MakeCallback(env->onread_string(), ARRAY_SIZE(argv), argv);
+ wrap()->MakeCallback(env->onread_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_READ);
}
diff --git a/src/stream_wrap.h b/src/stream_wrap.h
index f91bb8b..1059eb7 100644
--- a/src/stream_wrap.h
+++ b/src/stream_wrap.h
@@ -33,12 +33,12 @@ namespace node {
// Forward declaration
class StreamWrap;
-typedef class ReqWrap<uv_shutdown_t> ShutdownWrap;
+typedef class ReqWrap<uv_shutdown_t, PROVIDER_SHUTDOWN> ShutdownWrap;
-class WriteWrap: public ReqWrap<uv_write_t> {
+class WriteWrap: public ReqWrap<uv_write_t, PROVIDER_WRITEWRAP> {
public:
WriteWrap(Environment* env, v8::Local<v8::Object> obj, StreamWrap* wrap)
- : ReqWrap<uv_write_t>(env, obj),
+ : ReqWrap<uv_write_t, PROVIDER_WRITEWRAP>(env, obj),
wrap_(wrap) {
}
@@ -150,7 +150,8 @@ class StreamWrap : public HandleWrap {
StreamWrap(Environment* env,
v8::Local<v8::Object> object,
- uv_stream_t* stream);
+ uv_stream_t* stream,
+ AsyncProviderType provider);
~StreamWrap() {
if (callbacks_ != &default_callbacks_) {
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 99d71bf..07ca96e 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -50,7 +50,7 @@ using v8::String;
using v8::Undefined;
using v8::Value;
-typedef class ReqWrap<uv_connect_t> ConnectWrap;
+typedef class ReqWrap<uv_connect_t, PROVIDER_TCPWRAP> ConnectWrap;
Local<Object> TCPWrap::Instantiate(Environment* env) {
@@ -134,12 +134,16 @@ void TCPWrap::New(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
TCPWrap* wrap = new TCPWrap(env, args.This());
+ wrap->Create();
assert(wrap);
}
TCPWrap::TCPWrap(Environment* env, Handle<Object> object)
- : StreamWrap(env, object, reinterpret_cast<uv_stream_t*>(&handle_)) {
+ : StreamWrap(env,
+ object,
+ reinterpret_cast<uv_stream_t*>(&handle_),
+ PROVIDER_TCPWRAP) {
int r = uv_tcp_init(env->event_loop(), &handle_);
assert(r == 0); // How do we proxy this error up to javascript?
// Suggestion: uv_tcp_init() returns void.
@@ -327,7 +331,10 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
argv[1] = client_obj;
}
- tcp_wrap->MakeCallback(env->onconnection_string(), ARRAY_SIZE(argv), argv);
+ tcp_wrap->MakeCallback(env->onconnection_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_CONNECTION);
}
@@ -353,7 +360,10 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) {
v8::True(node_isolate)
};
- req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
+ req_wrap->MakeCallback(env->oncomplete_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_AFTER_CONNECTION);
delete req_wrap;
}
@@ -378,6 +388,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
if (err == 0) {
ConnectWrap* req_wrap = new ConnectWrap(env, req_wrap_obj);
+ req_wrap->Create();
err = uv_tcp_connect(&req_wrap->req_,
&wrap->handle_,
reinterpret_cast<const sockaddr*>(&addr),
@@ -410,6 +421,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
if (err == 0) {
ConnectWrap* req_wrap = new ConnectWrap(env, req_wrap_obj);
+ req_wrap->Create();
err = uv_tcp_connect(&req_wrap->req_,
&wrap->handle_,
reinterpret_cast<const sockaddr*>(&addr),
diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc
index e82f903..0a61831 100644
--- a/src/timer_wrap.cc
+++ b/src/timer_wrap.cc
@@ -79,11 +79,15 @@ class TimerWrap : public HandleWrap {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new TimerWrap(env, args.This());
+ TimerWrap *tw = new TimerWrap(env, args.This());
+ tw->Create();
}
TimerWrap(Environment* env, Handle<Object> object)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ : HandleWrap(env,
+ object,
+ reinterpret_cast<uv_handle_t*>(&handle_),
+ PROVIDER_TIMER) {
int r = uv_timer_init(env->event_loop(), &handle_);
assert(r == 0);
}
@@ -140,7 +144,7 @@ class TimerWrap : public HandleWrap {
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
Local<Value> argv[1] = { Integer::New(status, node_isolate) };
- wrap->MakeCallback(kOnTimeout, ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(kOnTimeout, ARRAY_SIZE(argv), argv, PROBE_TIMEOUT);
}
static void Now(const FunctionCallbackInfo<Value>& args) {
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 92febc1..280ac56 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -68,7 +68,9 @@ TLSCallbacks::TLSCallbacks(Environment* env,
StreamWrapCallbacks* old)
: SSLWrap<TLSCallbacks>(env, Unwrap<SecureContext>(sc), kind),
StreamWrapCallbacks(old),
- AsyncWrap(env, env->tls_wrap_constructor_function()->NewInstance()),
+ AsyncWrap(env,
+ env->tls_wrap_constructor_function()->NewInstance(),
+ PROVIDER_TLSWRAP),
sc_(Unwrap<SecureContext>(sc)),
sc_handle_(env->isolate(), sc),
enc_in_(NULL),
@@ -216,6 +218,7 @@ void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
TLSCallbacks* callbacks = NULL;
WITH_GENERIC_STREAM(env, stream, {
callbacks = new TLSCallbacks(env, kind, sc, wrap->callbacks());
+ callbacks->Create();
wrap->OverrideCallbacks(callbacks);
});
@@ -284,7 +287,7 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
if (where & SSL_CB_HANDSHAKE_START) {
Local<Value> callback = object->Get(env->onhandshakestart_string());
if (callback->IsFunction()) {
- c->MakeCallback(callback.As<Function>(), 0, NULL);
+ c->MakeCallback(callback.As<Function>(), 0, NULL, PROBE_SNI);
}
}
@@ -292,7 +295,7 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
c->established_ = true;
Local<Value> callback = object->Get(env->onhandshakedone_string());
if (callback->IsFunction()) {
- c->MakeCallback(callback.As<Function>(), 0, NULL);
+ c->MakeCallback(callback.As<Function>(), 0, NULL, PROBE_SNI);
}
}
}
@@ -443,7 +446,10 @@ void TLSCallbacks::ClearOut() {
Integer::New(read, node_isolate),
Buffer::New(env(), out, read)
};
- wrap()->MakeCallback(env()->onread_string(), ARRAY_SIZE(argv), argv);
+ wrap()->MakeCallback(env()->onread_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_READ);
}
} while (read > 0);
@@ -451,7 +457,7 @@ void TLSCallbacks::ClearOut() {
if (!eof_ && flags & SSL_RECEIVED_SHUTDOWN) {
eof_ = true;
Local<Value> arg = Integer::New(UV_EOF, node_isolate);
- wrap()->MakeCallback(env()->onread_string(), 1, &arg);
+ wrap()->MakeCallback(env()->onread_string(), 1, &arg, PROBE_ON_READ);
}
if (read == -1) {
@@ -459,7 +465,7 @@ void TLSCallbacks::ClearOut() {
Local<Value> arg = GetSSLError(read, &err, NULL);
if (!arg.IsEmpty()) {
- MakeCallback(env()->onerror_string(), 1, &arg);
+ MakeCallback(env()->onerror_string(), 1, &arg, PROBE_ERROR);
}
}
}
@@ -618,7 +624,7 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,
HandleScope handle_scope(env()->isolate());
Context::Scope context_scope(env()->context());
Local<Value> arg = Integer::New(nread, node_isolate);
- wrap()->MakeCallback(env()->onread_string(), 1, &arg);
+ wrap()->MakeCallback(env()->onread_string(), 1, &arg, PROBE_ON_READ);
return;
}
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index b1a354a..6b26c43 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -169,12 +169,16 @@ void TTYWrap::New(const FunctionCallbackInfo<Value>& args) {
assert(fd >= 0);
TTYWrap* wrap = new TTYWrap(env, args.This(), fd, args[1]->IsTrue());
+ wrap->Create();
wrap->UpdateWriteQueueSize();
}
TTYWrap::TTYWrap(Environment* env, Handle<Object> object, int fd, bool readable)
- : StreamWrap(env, object, reinterpret_cast<uv_stream_t*>(&handle_)) {
+ : StreamWrap(env,
+ object,
+ reinterpret_cast<uv_stream_t*>(&handle_),
+ PROVIDER_TTYWRAP) {
uv_tty_init(env->event_loop(), &handle_, fd, readable);
}
diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc
index b5ae878..0ad5eb1 100644
--- a/src/udp_wrap.cc
+++ b/src/udp_wrap.cc
@@ -50,7 +50,7 @@ using v8::Undefined;
using v8::Value;
-class SendWrap : public ReqWrap<uv_udp_send_t> {
+class SendWrap : public ReqWrap<uv_udp_send_t, PROVIDER_UDPWRAP> {
public:
SendWrap(Environment* env, Local<Object> req_wrap_obj, bool have_callback);
inline bool have_callback() const;
@@ -62,7 +62,7 @@ class SendWrap : public ReqWrap<uv_udp_send_t> {
SendWrap::SendWrap(Environment* env,
Local<Object> req_wrap_obj,
bool have_callback)
- : ReqWrap<uv_udp_send_t>(env, req_wrap_obj),
+ : ReqWrap<uv_udp_send_t, PROVIDER_UDPWRAP>(env, req_wrap_obj),
have_callback_(have_callback) {
}
@@ -73,7 +73,10 @@ inline bool SendWrap::have_callback() const {
UDPWrap::UDPWrap(Environment* env, Handle<Object> object)
- : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ : HandleWrap(env,
+ object,
+ reinterpret_cast<uv_handle_t*>(&handle_),
+ PROVIDER_UDPWRAP) {
int r = uv_udp_init(env->event_loop(), &handle_);
assert(r == 0); // can't fail anyway
}
@@ -128,7 +131,8 @@ void UDPWrap::New(const FunctionCallbackInfo<Value>& args) {
assert(args.IsConstructCall());
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
- new UDPWrap(env, args.This());
+ UDPWrap *uw = new UDPWrap(env, args.This());
+ uw->Create();
}
@@ -266,6 +270,7 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
assert(length <= Buffer::Length(buffer_obj) - offset);
SendWrap* req_wrap = new SendWrap(env, req_wrap_obj, have_callback);
+ req_wrap->Create();
uv_buf_t buf = uv_buf_init(Buffer::Data(buffer_obj) + offset,
length);
@@ -364,7 +369,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
Local<Value> arg = Integer::New(status, node_isolate);
- req_wrap->MakeCallback(env->oncomplete_string(), 1, &arg);
+ req_wrap->MakeCallback(env->oncomplete_string(), 1, &arg, PROBE_ON_WRITE);
}
delete req_wrap;
}
@@ -411,14 +416,20 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
if (nread < 0) {
if (buf->base != NULL)
free(buf->base);
- wrap->MakeCallback(env->onmessage_string(), ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(env->onmessage_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_READ);
return;
}
char* base = static_cast<char*>(realloc(buf->base, nread));
argv[2] = Buffer::Use(env, base, nread);
argv[3] = AddressToJS(env, addr);
- wrap->MakeCallback(env->onmessage_string(), ARRAY_SIZE(argv), argv);
+ wrap->MakeCallback(env->onmessage_string(),
+ ARRAY_SIZE(argv),
+ argv,
+ PROBE_ON_READ);
}
--
1.8.3.4 (Apple Git-47)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment