Created
February 3, 2014 23:48
-
-
Save tjfontaine/8794830 to your computer and use it in GitHub Desktop.
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
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