The tracing module is designed for instrumenting your Node application. It is
not meant for general purpose use.
-***Be very careful with callbacks used in conjunction with this module***
-
-Many of these callbacks interact directly with asynchronous subsystems in a
-synchronous fashion. That is to say, you may be in a callback where a call to
-`console.log()` could result in an infinite recursive loop. Also of note, many
-of these callbacks are in hot execution code paths. That is to say your
-callbacks are executed quite often in the normal operation of Node, so be wary
-of doing CPU bound or synchronous workloads in these functions. Consider a ring
-buffer and a timer to defer processing.
-
`require('tracing')` to use this module.
## v8
setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
```
-
-# Async Listeners
-
-The `AsyncListener` API is the JavaScript interface for the `AsyncWrap`
-class which allows developers to be notified about key events in the
-lifetime of an asynchronous event. Node performs a lot of asynchronous
-events internally, and significant use of this API may have a
-**significant performance impact** on your application.
-
-
-## tracing.createAsyncListener(callbacksObj[, userData])
-
-* `callbacksObj` {Object} Contains optional callbacks that will fire at
-specific times in the life cycle of the asynchronous event.
-* `userData` {Value} a value that will be passed to all callbacks.
-
-Returns a constructed `AsyncListener` object.
-
-To begin capturing asynchronous events pass either the `callbacksObj` or
-pass an existing `AsyncListener` instance to [`tracing.addAsyncListener()`][].
-The same `AsyncListener` instance can only be added once to the active
-queue, and subsequent attempts to add the instance will be ignored.
-
-To stop capturing pass the `AsyncListener` instance to
-[`tracing.removeAsyncListener()`][]. This does _not_ mean the
-`AsyncListener` previously added will stop triggering callbacks. Once
-attached to an asynchronous event it will persist with the lifetime of the
-asynchronous call stack.
-
-Explanation of function parameters:
-
-
-`callbacksObj`: An `Object` which may contain several optional fields:
-
-* `create(userData)`: A `Function` called when an asynchronous
-event is instantiated. If a `Value` is returned then it will be attached
-to the event and overwrite any value that had been passed to
-`tracing.createAsyncListener()`'s `userData` argument. If an initial
-`userData` was passed when created, then `create()` will
-receive that as a function argument.
-
-* `before(context, userData)`: A `Function` that is called immediately
-before the asynchronous callback is about to run. It will be passed both
-the `context` (i.e. `this`) of the calling function and the `userData`
-either returned from `create()` or passed during construction (if
-either occurred).
-
-* `after(context, userData)`: A `Function` called immediately after
-the asynchronous event's callback has run. Note this will not be called
-if the callback throws and the error is not handled.
-
-* `error(userData, error)`: A `Function` called if the event's
-callback threw. If this registered callback returns `true` then Node will
-assume the error has been properly handled and resume execution normally.
-When multiple `error()` callbacks have been registered only **one** of
-those callbacks needs to return `true` for `AsyncListener` to accept that
-the error has been handled, but all `error()` callbacks will always be run.
-
-`userData`: A `Value` (i.e. anything) that will be, by default,
-attached to all new event instances. This will be overwritten if a `Value`
-is returned by `create()`.
-
-Here is an example of overwriting the `userData`:
-
- tracing.createAsyncListener({
- create: function listener(value) {
- // value === true
- return false;
- }, {
- before: function before(context, value) {
- // value === false
- }
- }, true);
-
-**Note:** The [EventEmitter][], while used to emit status of an asynchronous
-event, is not itself asynchronous. So `create()` will not fire when
-an event is added, and `before()`/`after()` will not fire when emitted
-callbacks are called.
-
-
-## tracing.addAsyncListener(callbacksObj[, userData])
-## tracing.addAsyncListener(asyncListener)
-
-Returns a constructed `AsyncListener` object and immediately adds it to
-the listening queue to begin capturing asynchronous events.
-
-Function parameters can either be the same as
-[`tracing.createAsyncListener()`][], or a constructed `AsyncListener`
-object.
-
-Example usage for capturing errors:
-
- var fs = require('fs');
-
- var cntr = 0;
- var key = tracing.addAsyncListener({
- create: function onCreate() {
- return { uid: cntr++ };
- },
- before: function onBefore(context, storage) {
- // Write directly to stdout or we'll enter a recursive loop
- fs.writeSync(1, 'uid: ' + storage.uid + ' is about to run\n');
- },
- after: function onAfter(context, storage) {
- fs.writeSync(1, 'uid: ' + storage.uid + ' ran\n');
- },
- error: function onError(storage, err) {
- // Handle known errors
- if (err.message === 'everything is fine') {
- // Writing to stderr this time.
- fs.writeSync(2, 'handled error just threw:\n');
- fs.writeSync(2, err.stack + '\n');
- return true;
- }
- }
- });
-
- process.nextTick(function() {
- throw new Error('everything is fine');
- });
-
- // Output:
- // uid: 0 is about to run
- // handled error just threw:
- // Error: really, it's ok
- // at /tmp/test2.js:27:9
- // at process._tickCallback (node.js:583:11)
- // at Function.Module.runMain (module.js:492:11)
- // at startup (node.js:123:16)
- // at node.js:1012:3
-
-## tracing.removeAsyncListener(asyncListener)
-
-Removes the `AsyncListener` from the listening queue.
-
-Removing the `AsyncListener` from the active queue does _not_ mean the
-`asyncListener` callbacks will cease to fire on the events they've been
-registered. Subsequently, any asynchronous events fired during the
-execution of a callback will also have the same `asyncListener` callbacks
-attached for future execution. For example:
-
- var fs = require('fs');
-
- var key = tracing.createAsyncListener({
- create: function asyncListener() {
- // Write directly to stdout or we'll enter a recursive loop
- fs.writeSync(1, 'You summoned me?\n');
- }
- });
-
- // We want to begin capturing async events some time in the future.
- setTimeout(function() {
- tracing.addAsyncListener(key);
-
- // Perform a few additional async events.
- setTimeout(function() {
- setImmediate(function() {
- process.nextTick(function() { });
- });
- });
-
- // Removing the listener doesn't mean to stop capturing events that
- // have already been added.
- tracing.removeAsyncListener(key);
- }, 100);
-
- // Output:
- // You summoned me?
- // You summoned me?
- // You summoned me?
- // You summoned me?
-
-The fact that we logged 4 asynchronous events is an implementation detail
-of Node's [Timers][].
-
-To stop capturing from a specific asynchronous event stack
-`tracing.removeAsyncListener()` must be called from within the call
-stack itself. For example:
-
- var fs = require('fs');
-
- var key = tracing.createAsyncListener({
- create: function asyncListener() {
- // Write directly to stdout or we'll enter a recursive loop
- fs.writeSync(1, 'You summoned me?\n');
- }
- });
-
- // We want to begin capturing async events some time in the future.
- setTimeout(function() {
- tracing.addAsyncListener(key);
-
- // Perform a few additional async events.
- setImmediate(function() {
- // Stop capturing from this call stack.
- tracing.removeAsyncListener(key);
-
- process.nextTick(function() { });
- });
- }, 100);
-
- // Output:
- // You summoned me?
-
-The user must be explicit and always pass the `AsyncListener` they wish
-to remove. It is not possible to simply remove all listeners at once.
-
-
-[EventEmitter]: events.html#events_class_events_eventemitter
-[Timers]: timers.html
-[`tracing.createAsyncListener()`]: #tracing_tracing_createasynclistener_asynclistener_callbacksobj_storagevalue
-[`tracing.addAsyncListener()`]: #tracing_tracing_addasynclistener_asynclistener
-[`tracing.removeAsyncListener()`]: #tracing_tracing_removeasynclistener_asynclistener
+
var debug = require('util').debuglog('timer');
-var tracing = require('tracing');
-var asyncFlags = tracing._asyncFlags;
-var runAsyncQueue = tracing._runAsyncQueue;
-var loadAsyncQueue = tracing._loadAsyncQueue;
-var unloadAsyncQueue = tracing._unloadAsyncQueue;
-
-// Same as in AsyncListener in env.h
-var kHasListener = 0;
-
-// Do a little housekeeping.
-delete tracing._asyncFlags;
-delete tracing._runAsyncQueue;
-delete tracing._loadAsyncQueue;
-delete tracing._unloadAsyncQueue;
-
// IDLE TIMEOUTS
//
// value = list
var lists = {};
-// Make Timer as monomorphic as possible.
-Timer.prototype._asyncQueue = undefined;
-Timer.prototype._asyncData = undefined;
-Timer.prototype._asyncFlags = 0;
-
// the main function - creates lists on demand and the watchers associated
// with them.
function insert(item, msecs) {
var now = Timer.now();
debug('now: %s', now);
- var diff, first, hasQueue, threw;
+ var diff, first, threw;
while (first = L.peek(list)) {
diff = now - first._idleStart;
if (diff < msecs) {
if (domain && domain._disposed)
continue;
- hasQueue = !!first._asyncQueue;
-
try {
- if (hasQueue)
- loadAsyncQueue(first);
if (domain)
domain.enter();
threw = true;
first._onTimeout();
if (domain)
domain.exit();
- if (hasQueue)
- unloadAsyncQueue(first);
threw = false;
} finally {
if (threw) {
L.append(list, item);
}
}
- // Whether or not a new TimerWrap needed to be created, this should run
- // for each item. This way each "item" (i.e. timer) can properly have
- // their own domain assigned.
- if (asyncFlags[kHasListener] > 0)
- runAsyncQueue(item);
};
function processImmediate() {
var queue = immediateQueue;
- var domain, hasQueue, immediate;
+ var domain, immediate;
immediateQueue = {};
L.init(immediateQueue);
while (L.isEmpty(queue) === false) {
immediate = L.shift(queue);
- hasQueue = !!immediate._asyncQueue;
domain = immediate.domain;
- if (hasQueue)
- loadAsyncQueue(immediate);
if (domain)
domain.enter();
if (domain)
domain.exit();
- if (hasQueue)
- unloadAsyncQueue(immediate);
}
// Only round-trip to C++ land if we have to. Calling clearImmediate() on an
Immediate.prototype.domain = undefined;
Immediate.prototype._onImmediate = undefined;
-Immediate.prototype._asyncQueue = undefined;
-Immediate.prototype._asyncData = undefined;
Immediate.prototype._idleNext = undefined;
Immediate.prototype._idlePrev = undefined;
-Immediate.prototype._asyncFlags = 0;
exports.setImmediate = function(callback) {
process._immediateCallback = processImmediate;
}
- // setImmediates are handled more like nextTicks.
- if (asyncFlags[kHasListener] > 0)
- runAsyncQueue(immediate);
if (process.domain)
immediate.domain = process.domain;
debug('unrefTimer fired');
- var diff, domain, first, hasQueue, threw;
+ var diff, domain, first, threw;
while (first = L.peek(unrefList)) {
diff = now - first._idleStart;
if (!first._onTimeout) continue;
if (domain && domain._disposed) continue;
- hasQueue = !!first._asyncQueue;
try {
- if (hasQueue)
- loadAsyncQueue(first);
if (domain) domain.enter();
threw = true;
debug('unreftimer firing timeout');
threw = false;
if (domain)
domain.exit();
- if (hasQueue)
- unloadAsyncQueue(first);
} finally {
if (threw) process.nextTick(unrefTimeout);
}
v8.getHeapStatistics = v8binding.getHeapStatistics;
v8.setFlagsFromString = v8binding.setFlagsFromString;
- // Part of the AsyncListener setup to share objects/callbacks with the
- // native layer.
- process._setupAsyncListener(asyncFlags,
- runAsyncQueue,
- loadAsyncQueue,
- unloadAsyncQueue);
-
// Do a little housekeeping.
delete exports._nodeInitialization;
};
}
});
-
-// AsyncListener
-
-// new Array() is used here because it is more efficient for sparse
-// arrays. Please *do not* change these to simple bracket notation.
-
-// Track the active queue of AsyncListeners that have been added.
-var asyncQueue = new Array();
-
-// Keep the stack of all contexts that have been loaded in the
-// execution chain of asynchronous events.
-var contextStack = new Array();
-var currentContext = undefined;
-
-// Incremental uid for new AsyncListener instances.
-var alUid = 0;
-
-// Stateful flags shared with Environment for quick JS/C++
-// communication.
-var asyncFlags = {};
-
-// Prevent accidentally suppressed thrown errors from before/after.
-var inAsyncTick = false;
-
-// To prevent infinite recursion when an error handler also throws
-// flag when an error is currenly being handled.
-var inErrorTick = false;
-
-// Needs to be the same as src/env.h
-var kHasListener = 0;
-
-// Flags to determine what async listeners are available.
-var HAS_CREATE_AL = 1 << 0;
-var HAS_BEFORE_AL = 1 << 1;
-var HAS_AFTER_AL = 1 << 2;
-var HAS_ERROR_AL = 1 << 3;
-
-// _errorHandler is scoped so it's also accessible by _fatalException.
-exports._errorHandler = errorHandler;
-
-// Needs to be accessible from lib/timers.js so they know when async
-// listeners are currently in queue. They'll be cleaned up once
-// references there are made.
-exports._asyncFlags = asyncFlags;
-exports._runAsyncQueue = runAsyncQueue;
-exports._loadAsyncQueue = loadAsyncQueue;
-exports._unloadAsyncQueue = unloadAsyncQueue;
-
-// Public API.
-exports.createAsyncListener = createAsyncListener;
-exports.addAsyncListener = addAsyncListener;
-exports.removeAsyncListener = removeAsyncListener;
-
-// Load the currently executing context as the current context, and
-// create a new asyncQueue that can receive any added queue items
-// during the executing of the callback.
-function loadContext(ctx) {
- contextStack.push(currentContext);
- currentContext = ctx;
-
- asyncFlags[kHasListener] = 1;
-}
-
-function unloadContext() {
- currentContext = contextStack.pop();
-
- if (currentContext === undefined && asyncQueue.length === 0)
- asyncFlags[kHasListener] = 0;
-}
-
-// Run all the async listeners attached when an asynchronous event is
-// instantiated.
-function runAsyncQueue(context) {
- var queue = new Array();
- var data = new Array();
- var ccQueue, i, queueItem, value;
-
- context._asyncQueue = queue;
- context._asyncData = data;
- context._asyncFlags = 0;
-
- inAsyncTick = true;
-
- // First run through all callbacks in the currentContext. These may
- // add new AsyncListeners to the asyncQueue during execution. Hence
- // why they need to be evaluated first.
- if (currentContext) {
- ccQueue = currentContext._asyncQueue;
- context._asyncFlags |= currentContext._asyncFlags;
- for (i = 0; i < ccQueue.length; i++) {
- queueItem = ccQueue[i];
- queue[queue.length] = queueItem;
- if ((queueItem.callback_flags & HAS_CREATE_AL) === 0) {
- data[queueItem.uid] = queueItem.data;
- continue;
- }
- value = queueItem.create(queueItem.data);
- data[queueItem.uid] = (value === undefined) ? queueItem.data : value;
- }
- }
-
- // Then run through all items in the asyncQueue
- if (asyncQueue) {
- for (i = 0; i < asyncQueue.length; i++) {
- queueItem = asyncQueue[i];
- // Quick way to check if an AL instance with the same uid was
- // already run from currentContext.
- if (data[queueItem.uid] !== undefined)
- continue;
- queue[queue.length] = queueItem;
- context._asyncFlags |= queueItem.callback_flags;
- if ((queueItem.callback_flags & HAS_CREATE_AL) === 0) {
- data[queueItem.uid] = queueItem.data;
- continue;
- }
- value = queueItem.create(queueItem.data);
- data[queueItem.uid] = (value === undefined) ? queueItem.data : value;
- }
- }
-
- inAsyncTick = false;
-}
-
-// Load the AsyncListener queue attached to context and run all
-// "before" callbacks, if they exist.
-function loadAsyncQueue(context) {
- loadContext(context);
-
- if ((context._asyncFlags & HAS_BEFORE_AL) === 0)
- return;
-
- var queue = context._asyncQueue;
- var data = context._asyncData;
- var i, queueItem;
-
- inAsyncTick = true;
- for (i = 0; i < queue.length; i++) {
- queueItem = queue[i];
- if ((queueItem.callback_flags & HAS_BEFORE_AL) > 0)
- queueItem.before(context, data[queueItem.uid]);
- }
- inAsyncTick = false;
-}
-
-// Unload the AsyncListener queue attached to context and run all
-// "after" callbacks, if they exist.
-function unloadAsyncQueue(context) {
- if ((context._asyncFlags & HAS_AFTER_AL) === 0) {
- unloadContext();
- return;
- }
-
- var queue = context._asyncQueue;
- var data = context._asyncData;
- var i, queueItem;
-
- inAsyncTick = true;
- for (i = 0; i < queue.length; i++) {
- queueItem = queue[i];
- if ((queueItem.callback_flags & HAS_AFTER_AL) > 0)
- queueItem.after(context, data[queueItem.uid]);
- }
- inAsyncTick = false;
-
- unloadContext();
-}
-
-// Handle errors that are thrown while in the context of an
-// AsyncListener. If an error is thrown from an AsyncListener
-// callback error handlers will be called once more to report
-// the error, then the application will die forcefully.
-function errorHandler(er) {
- if (inErrorTick)
- return false;
-
- var handled = false;
- var i, queueItem, threw;
-
- inErrorTick = true;
-
- // First process error callbacks from the current context.
- if (currentContext && (currentContext._asyncFlags & HAS_ERROR_AL) > 0) {
- var queue = currentContext._asyncQueue;
- var data = currentContext._asyncData;
- for (i = 0; i < queue.length; i++) {
- queueItem = queue[i];
- if ((queueItem.callback_flags & HAS_ERROR_AL) === 0)
- continue;
- try {
- threw = true;
- // While it would be possible to pass in currentContext, if
- // the error is thrown from the "create" callback then there's
- // a chance the object hasn't been fully constructed.
- handled = queueItem.error(data[queueItem.uid], er) || handled;
- threw = false;
- } finally {
- // If the error callback thew then die quickly. Only allow the
- // exit events to be processed.
- if (threw) {
- process._exiting = true;
- process.emit('exit', 1);
- }
- }
- }
- }
-
- // Now process callbacks from any existing queue.
- if (asyncQueue) {
- for (i = 0; i < asyncQueue.length; i++) {
- queueItem = asyncQueue[i];
- if ((queueItem.callback_flags & HAS_ERROR_AL) === 0 ||
- (data && data[queueItem.uid] !== undefined))
- continue;
- try {
- threw = true;
- handled = queueItem.error(queueItem.data, er) || handled;
- threw = false;
- } finally {
- // If the error callback thew then die quickly. Only allow the
- // exit events to be processed.
- if (threw) {
- process._exiting = true;
- process.emit('exit', 1);
- }
- }
- }
- }
-
- inErrorTick = false;
-
- unloadContext();
-
- // TODO(trevnorris): If the error was handled, should the after callbacks
- // be fired anyways?
-
- return handled && !inAsyncTick;
-}
-
-// Instance function of an AsyncListener object.
-function AsyncListenerInst(callbacks, data) {
- if (typeof callbacks.create === 'function') {
- this.create = callbacks.create;
- this.callback_flags |= HAS_CREATE_AL;
- }
- if (typeof callbacks.before === 'function') {
- this.before = callbacks.before;
- this.callback_flags |= HAS_BEFORE_AL;
- }
- if (typeof callbacks.after === 'function') {
- this.after = callbacks.after;
- this.callback_flags |= HAS_AFTER_AL;
- }
- if (typeof callbacks.error === 'function') {
- this.error = callbacks.error;
- this.callback_flags |= HAS_ERROR_AL;
- }
-
- this.uid = ++alUid;
- this.data = data === undefined ? null : data;
-}
-AsyncListenerInst.prototype.create = undefined;
-AsyncListenerInst.prototype.before = undefined;
-AsyncListenerInst.prototype.after = undefined;
-AsyncListenerInst.prototype.error = undefined;
-AsyncListenerInst.prototype.data = undefined;
-AsyncListenerInst.prototype.uid = 0;
-AsyncListenerInst.prototype.callback_flags = 0;
-
-// Create new async listener object. Useful when instantiating a new
-// object and want the listener instance, but not add it to the stack.
-// If an existing AsyncListenerInst is passed then any new "data" is
-// ignored.
-function createAsyncListener(callbacks, data) {
- if (typeof callbacks !== 'object' || callbacks == null)
- throw new TypeError('callbacks argument must be an object');
-
- if (callbacks instanceof AsyncListenerInst)
- return callbacks;
- else
- return new AsyncListenerInst(callbacks, data);
-}
-
-// Add a listener to the current queue.
-function addAsyncListener(callbacks, data) {
- // Fast track if a new AsyncListenerInst has to be created.
- if (!(callbacks instanceof AsyncListenerInst)) {
- callbacks = createAsyncListener(callbacks, data);
- asyncQueue.push(callbacks);
- asyncFlags[kHasListener] = 1;
- return callbacks;
- }
-
- var inQueue = false;
- // The asyncQueue will be small. Probably always <= 3 items.
- for (var i = 0; i < asyncQueue.length; i++) {
- if (callbacks === asyncQueue[i]) {
- inQueue = true;
- break;
- }
- }
-
- // Make sure the callback doesn't already exist in the queue.
- if (!inQueue) {
- asyncQueue.push(callbacks);
- asyncFlags[kHasListener] = 1;
- }
-
- return callbacks;
-}
-
-// Remove listener from the current queue. Though this will not remove
-// the listener from the current context. So callback propagation will
-// continue.
-function removeAsyncListener(obj) {
- for (var i = 0; i < asyncQueue.length; i++) {
- if (obj === asyncQueue[i]) {
- asyncQueue.splice(i, 1);
- break;
- }
- }
-
- if (asyncQueue.length > 0 || currentContext !== undefined)
- asyncFlags[kHasListener] = 1;
- else
- asyncFlags[kHasListener] = 0;
-}
v8::Handle<v8::Object> object,
ProviderType provider)
: BaseObject(env, object),
- async_flags_(NO_OPTIONS),
provider_type_(provider) {
- 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);
-
- if (!try_catch.HasCaught())
- async_flags_ |= HAS_ASYNC_LISTENER;
}
}
-inline bool AsyncWrap::has_async_listener() {
- return async_flags_ & HAS_ASYNC_LISTENER;
-}
-
-
// I hate you domains.
inline v8::Handle<v8::Value> AsyncWrap::MakeDomainCallback(
const v8::Handle<v8::Function> cb,
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
- 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())
- return v8::Undefined(env()->isolate());
- }
-
bool has_domain = domain_v->IsObject();
if (has_domain) {
domain = domain_v.As<v8::Object>();
}
}
- 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())
- return Undefined(env()->isolate());
- }
-
Environment::TickInfo* tick_info = env()->tick_info();
if (tick_info->in_tick()) {
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
- 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())
- return v8::Undefined(env()->isolate());
- }
-
v8::Local<v8::Value> ret = cb->Call(context, argc, argv);
if (try_catch.HasCaught()) {
return Undefined(env()->isolate());
}
- 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())
- return v8::Undefined(env()->isolate());
- }
-
Environment::TickInfo* tick_info = env()->tick_info();
if (tick_info->in_tick()) {
class AsyncWrap : public BaseObject {
public:
- enum AsyncFlags {
- NO_OPTIONS = 0,
- HAS_ASYNC_LISTENER = 1
- };
-
enum ProviderType {
PROVIDER_NONE = 1 << 0,
PROVIDER_CARES = 1 << 1,
inline virtual ~AsyncWrap() override = default;
- inline bool has_async_listener();
-
inline uint32_t provider_type() const;
// Only call these within a valid HandleScope.
int argc,
v8::Handle<v8::Value>* argv);
- uint32_t async_flags_;
uint32_t provider_type_;
};
return isolate_;
}
-inline Environment::AsyncListener::AsyncListener() {
- for (int i = 0; i < kFieldsCount; ++i)
- fields_[i] = 0;
-}
-
-inline uint32_t* Environment::AsyncListener::fields() {
- return fields_;
-}
-
-inline int Environment::AsyncListener::fields_count() const {
- return kFieldsCount;
-}
-
-inline bool Environment::AsyncListener::has_listener() const {
- return fields_[kHasListener] > 0;
-}
-
-inline uint32_t Environment::AsyncListener::watched_providers() const {
- return fields_[kWatchedProviders];
-}
-
inline Environment::DomainFlag::DomainFlag() {
for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0;
}
return isolate_;
}
-inline bool Environment::has_async_listener() const {
- // The const_cast is okay, it doesn't violate conceptual const-ness.
- return const_cast<Environment*>(this)->async_listener()->has_listener();
-}
-
-inline uint32_t Environment::watched_providers() const {
- // The const_cast is okay, it doesn't violate conceptual const-ness.
- return const_cast<Environment*>(this)->async_listener()->watched_providers();
-}
-
inline bool Environment::in_domain() const {
// The const_cast is okay, it doesn't violate conceptual const-ness.
return using_domains() &&
return isolate_data()->event_loop();
}
-inline Environment::AsyncListener* Environment::async_listener() {
- return &async_listener_count_;
-}
-
inline Environment::DomainFlag* Environment::domain_flag() {
return &domain_flag_;
}
V(address_string, "address") \
V(args_string, "args") \
V(argv_string, "argv") \
- V(async_queue_string, "_asyncQueue") \
V(async, "async") \
V(atime_string, "atime") \
V(birthtime_string, "birthtime") \
V(zero_return_string, "ZERO_RETURN") \
#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \
- V(async_listener_run_function, v8::Function) \
- V(async_listener_load_function, v8::Function) \
- V(async_listener_unload_function, v8::Function) \
V(binding_cache_object, v8::Object) \
V(buffer_constructor_function, v8::Function) \
V(context, v8::Context) \
class Environment {
public:
- class AsyncListener {
- public:
- inline uint32_t* fields();
- inline int fields_count() const;
- inline bool has_listener() const;
- inline uint32_t watched_providers() const;
-
- private:
- friend class Environment; // So we can call the constructor.
- inline AsyncListener();
-
- enum Fields {
- kHasListener,
- kWatchedProviders,
- kFieldsCount
- };
-
- uint32_t fields_[kFieldsCount];
-
- DISALLOW_COPY_AND_ASSIGN(AsyncListener);
- };
-
class DomainFlag {
public:
inline uint32_t* fields();
inline v8::Isolate* isolate() const;
inline uv_loop_t* event_loop() const;
- inline bool has_async_listener() const;
inline bool in_domain() const;
inline uint32_t watched_providers() const;
void *arg);
inline void FinishHandleCleanup(uv_handle_t* handle);
- inline AsyncListener* async_listener();
inline DomainFlag* domain_flag();
inline TickInfo* tick_info();
uv_idle_t immediate_idle_handle_;
uv_prepare_t idle_prepare_handle_;
uv_check_t idle_check_handle_;
- AsyncListener async_listener_count_;
DomainFlag domain_flag_;
TickInfo tick_info_;
uv_timer_t cares_timer_handle_;
#endif
-void SetupAsyncListener(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- CHECK(args[0]->IsObject());
- CHECK(args[1]->IsFunction());
- CHECK(args[2]->IsFunction());
- CHECK(args[3]->IsFunction());
-
- env->set_async_listener_run_function(args[1].As<Function>());
- env->set_async_listener_load_function(args[2].As<Function>());
- env->set_async_listener_unload_function(args[3].As<Function>());
-
- Local<Object> async_listener_flag_obj = args[0].As<Object>();
- Environment::AsyncListener* async_listener = env->async_listener();
- async_listener_flag_obj->SetIndexedPropertiesToExternalArrayData(
- async_listener->fields(),
- kExternalUint32Array,
- async_listener->fields_count());
-
- // Do a little housekeeping.
- env->process_object()->Delete(
- FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupAsyncListener"));
-}
-
-
void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
TryCatch try_catch;
try_catch.SetVerbose(true);
- bool has_async_queue = false;
-
- if (recv->IsObject()) {
- object = recv.As<Object>();
- // TODO(trevnorris): This is sucky for performance. Fix it.
- has_async_queue = object->Has(env->async_queue_string());
- if (has_async_queue) {
- env->async_listener_load_function()->Call(process, 1, &recv);
-
- if (try_catch.HasCaught())
- return Undefined(env->isolate());
- }
- }
-
bool has_domain = false;
if (!object.IsEmpty()) {
}
}
- if (has_async_queue) {
- env->async_listener_unload_function()->Call(process, 1, &recv);
-
- if (try_catch.HasCaught())
- return Undefined(env->isolate());
- }
-
Environment::TickInfo* tick_info = env->tick_info();
if (tick_info->last_threw() == 1) {
TryCatch try_catch;
try_catch.SetVerbose(true);
- // TODO(trevnorris): This is sucky for performance. Fix it.
- bool has_async_queue =
- recv->IsObject() && recv.As<Object>()->Has(env->async_queue_string());
- if (has_async_queue) {
- env->async_listener_load_function()->Call(process, 1, &recv);
- if (try_catch.HasCaught())
- return Undefined(env->isolate());
- }
-
Local<Value> ret = callback->Call(recv, argc, argv);
if (try_catch.HasCaught()) {
return Undefined(env->isolate());
}
- if (has_async_queue) {
- env->async_listener_unload_function()->Call(process, 1, &recv);
-
- if (try_catch.HasCaught())
- return Undefined(env->isolate());
- }
-
Environment::TickInfo* tick_info = env->tick_info();
if (tick_info->in_tick()) {
env->SetMethod(process, "binding", Binding);
env->SetMethod(process, "_linkedBinding", LinkedBinding);
- env->SetMethod(process, "_setupAsyncListener", SetupAsyncListener);
env->SetMethod(process, "_setupNextTick", SetupNextTick);
env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
};
startup.processFatal = function() {
- var tracing = NativeModule.require('tracing');
- var _errorHandler = tracing._errorHandler;
- // Cleanup
- delete tracing._errorHandler;
-
process._fatalException = function(er) {
- // First run through error handlers from asyncListener.
- var caught = _errorHandler(er);
+ var caught;
if (process.domain && process.domain._errorHandler)
caught = process.domain._errorHandler(er) || caught;
// if we handled an error, then make sure any ticks get processed
} else {
var t = setImmediate(process._tickCallback);
- // Complete hack to make sure any errors thrown from async
- // listeners don't cause an infinite loop.
- if (t._asyncQueue)
- t._asyncQueue = [];
}
return caught;
};
startup.processNextTick = function() {
- var tracing = NativeModule.require('tracing');
var nextTickQueue = [];
- var asyncFlags = tracing._asyncFlags;
- var _runAsyncQueue = tracing._runAsyncQueue;
- var _loadAsyncQueue = tracing._loadAsyncQueue;
- var _unloadAsyncQueue = tracing._unloadAsyncQueue;
var microtasksScheduled = false;
// Used to run V8's micro task queue.
var kIndex = 0;
var kLength = 1;
- // For asyncFlags.
- // *Must* match Environment::AsyncListeners::Fields in src/env.h
- var kCount = 0;
-
process.nextTick = nextTick;
// Needs to be accessible from beyond this scope.
process._tickCallback = _tickCallback;
// Run callbacks that have no domain.
// Using domains will cause this to be overridden.
function _tickCallback() {
- var callback, hasQueue, threw, tock;
+ var callback, threw, tock;
scheduleMicrotasks();
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
threw = true;
- hasQueue = !!tock._asyncQueue;
- if (hasQueue)
- _loadAsyncQueue(tock);
try {
callback();
threw = false;
if (threw)
tickDone();
}
- if (hasQueue)
- _unloadAsyncQueue(tock);
if (1e4 < tickInfo[kIndex])
tickDone();
}
}
function _tickDomainCallback() {
- var callback, domain, hasQueue, threw, tock;
+ var callback, domain, threw, tock;
scheduleMicrotasks();
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
domain = tock.domain;
- hasQueue = !!tock._asyncQueue;
- if (hasQueue)
- _loadAsyncQueue(tock);
if (domain)
domain.enter();
threw = true;
if (threw)
tickDone();
}
- if (hasQueue)
- _unloadAsyncQueue(tock);
if (1e4 < tickInfo[kIndex])
tickDone();
if (domain)
var obj = {
callback: callback,
- domain: process.domain || null,
- _asyncQueue: undefined
+ domain: process.domain || null
};
- if (asyncFlags[kCount] > 0)
- _runAsyncQueue(obj);
-
nextTickQueue.push(obj);
tickInfo[kLength]++;
}
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var active = null;
-var cntr = 0;
-
-function onAsync0() {
- return 0;
-}
-
-function onAsync1() {
- return 1;
-}
-
-function onError(stor) {
- results.push(stor);
- return true;
-}
-
-var results = [];
-var asyncNoHandleError0 = {
- create: onAsync0,
- error: onError
-};
-var asyncNoHandleError1 = {
- create: onAsync1,
- error: onError
-};
-
-var listeners = [
- tracing.addAsyncListener(asyncNoHandleError0),
- tracing.addAsyncListener(asyncNoHandleError1)
-];
-
-process.nextTick(function() {
- throw new Error();
-});
-
-tracing.removeAsyncListener(listeners[0]);
-tracing.removeAsyncListener(listeners[1]);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // Handling of errors should propagate to all listeners.
- assert.equal(results[0], 0);
- assert.equal(results[1], 1);
- assert.equal(results.length, 2);
-
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var results = [];
-var asyncNoHandleError = {
- error: function(stor) {
- results.push(1);
- }
-};
-
-var asyncHandleError = {
- error: function(stor) {
- results.push(0);
- return true;
- }
-};
-
-var listeners = [
- tracing.addAsyncListener(asyncHandleError),
- tracing.addAsyncListener(asyncNoHandleError)
-];
-
-// Even if an error handler returns true, both should fire.
-process.nextTick(function() {
- throw new Error();
-});
-
-tracing.removeAsyncListener(listeners[0]);
-tracing.removeAsyncListener(listeners[1]);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // Mixed handling of errors should propagate to all listeners.
- assert.equal(results[0], 0);
- assert.equal(results[1], 1);
- assert.equal(results.length, 2);
-
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-function onAsync0() {
- return 0;
-}
-
-function onAsync1() {
- return 1;
-}
-
-function onError(stor) {
- results.push(stor);
-}
-
-var results = [];
-var asyncNoHandleError0 = {
- create: onAsync0,
- error: onError
-};
-var asyncNoHandleError1 = {
- create: onAsync1,
- error: onError
-};
-
-var listeners = [
- tracing.addAsyncListener(asyncNoHandleError0),
- tracing.addAsyncListener(asyncNoHandleError1)
-];
-
-var uncaughtFired = false;
-process.on('uncaughtException', function() {
- uncaughtFired = true;
-
- // Unhandled errors should propagate to all listeners.
- assert.equal(results[0], 0);
- assert.equal(results[1], 1);
- assert.equal(results.length, 2);
-});
-
-process.nextTick(function() {
- throw new Error();
-});
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // Need to remove the async listeners or tests will always pass
- for (var i = 0; i < listeners.length; i++)
- tracing.removeAsyncListener(listeners[i]);
-
- assert.ok(uncaughtFired);
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var dns = require('dns');
-var fs = require('fs');
-var net = require('net');
-var tracing = require('tracing');
-
-var errorMsgs = [];
-var caught = 0;
-var expectCaught = 0;
-
-var callbacksObj = {
- error: function(value, er) {
- var idx = errorMsgs.indexOf(er.message);
- caught++;
-
- process._rawDebug('Handling error: ' + er.message);
-
- if (-1 < idx)
- errorMsgs.splice(idx, 1);
- else
- throw new Error('Message not found: ' + er.message);
-
- return true;
- }
-};
-
-var listener = tracing.addAsyncListener(callbacksObj);
-
-process.on('exit', function(code) {
- tracing.removeAsyncListener(listener);
-
- if (code > 0)
- return;
-
- if (errorMsgs.length > 0)
- throw new Error('Errors not fired: ' + errorMsgs);
-
- assert.equal(caught, expectCaught);
- process._rawDebug('ok');
-});
-
-
-// Net
-var iter = 3;
-for (var i = 0; i < iter; i++) {
- errorMsgs.push('net - error: server connection');
- errorMsgs.push('net - error: client data');
- errorMsgs.push('net - error: server data');
-}
-errorMsgs.push('net - error: server closed');
-
-var server = net.createServer(function(c) {
- c.on('data', function() {
- if (0 === --iter) {
- server.close(function() {
- process._rawDebug('net - server closing');
- throw new Error('net - error: server closed');
- });
- expectCaught++;
- }
- process._rawDebug('net - connection received data');
- throw new Error('net - error: server data');
- });
- expectCaught++;
-
- c.end('bye');
- process._rawDebug('net - connection received');
- throw new Error('net - error: server connection');
-});
-expectCaught += iter;
-
-server.listen(common.PORT, function() {
- for (var i = 0; i < iter; i++)
- clientConnect();
-});
-
-function clientConnect() {
- var client = net.connect(common.PORT, function() { });
-
- client.on('data', function() {
- client.end('see ya');
- process._rawDebug('net - client received data');
- throw new Error('net - error: client data');
- });
- expectCaught++;
-}
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var once = 0;
-
-var results = [];
-var handlers = {
- after: function() {
- throw 1;
- },
- error: function(stor, err) {
- // Error handler must be called exactly *once*.
- once++;
- assert.equal(err, 1);
- return true;
- }
-}
-
-var key = tracing.addAsyncListener(handlers);
-
-var uncaughtFired = false;
-process.on('uncaughtException', function(err) {
- uncaughtFired = true;
-
- assert.equal(once, 1);
-});
-
-process.nextTick(function() { });
-
-tracing.removeAsyncListener(key);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- assert.ok(uncaughtFired);
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var once = 0;
-
-var results = [];
-var handlers = {
- before: function() {
- throw 1;
- },
- error: function(stor, err) {
- // Must catch error thrown in before callback.
- assert.equal(err, 1);
- once++;
- return true;
- }
-}
-
-var handlers1 = {
- before: function() {
- throw 2;
- },
- error: function(stor, err) {
- // Must catch *other* handlers throw by error callback.
- assert.equal(err, 1);
- once++;
- return true;
- }
-}
-
-var listeners = [
- tracing.addAsyncListener(handlers),
- tracing.addAsyncListener(handlers1)
-];
-
-var uncaughtFired = false;
-process.on('uncaughtException', function(err) {
- uncaughtFired = true;
-
- // Both error handlers must fire.
- assert.equal(once, 2);
-});
-
-process.nextTick(function() { });
-
-for (var i = 0; i < listeners.length; i++)
- tracing.removeAsyncListener(listeners[i]);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
- // Make sure uncaughtException actually fired.
- assert.ok(uncaughtFired);
- console.log('ok');
-});
-
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var once = 0;
-
-var results = [];
-var handlers = {
- before: function() {
- throw 1;
- },
- error: function(stor, err) {
- // Error handler must be called exactly *once*.
- once++;
- assert.equal(err, 1);
- return true;
- }
-}
-
-var key = tracing.addAsyncListener(handlers);
-
-var uncaughtFired = false;
-process.on('uncaughtException', function(err) {
- uncaughtFired = true;
-
- // Process should propagate error regardless of handlers return value.
- assert.equal(once, 1);
-});
-
-process.nextTick(function() { });
-
-tracing.removeAsyncListener(key);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // Make sure that the uncaughtException actually fired.
- assert.ok(uncaughtFired);
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var spawn = require('child_process').spawn;
-var tracing = require('tracing');
-
-var checkStr = 'WRITTEN ON EXIT';
-
-if (process.argv[2] === 'child')
- runChild();
-else
- runParent();
-
-
-function runChild() {
- var cntr = 0;
-
- var key = tracing.addAsyncListener({
- error: function onError() {
- cntr++;
- throw new Error('onError');
- }
- });
-
- process.on('unhandledException', function() {
- // Throwing in 'error' should bypass unhandledException.
- process.exit(2);
- });
-
- process.on('exit', function() {
- // Make sure that we can still write out to stderr even when the
- // process dies.
- process._rawDebug(checkStr);
- });
-
- process.nextTick(function() {
- throw new Error('nextTick');
- });
-}
-
-
-function runParent() {
- var childDidExit = false;
- var childStr = '';
- var child = spawn(process.execPath, [__filename, 'child']);
- child.stderr.on('data', function(chunk) {
- process._rawDebug('received data from child');
- childStr += chunk.toString();
- });
-
- child.on('exit', function(code) {
- process._rawDebug('child process exiting');
- childDidExit = true;
- // This is thrown when Node throws from _fatalException.
- assert.equal(code, 7);
- });
-
- process.on('exit', function() {
- process._rawDebug('child ondata message:',
- childStr.substr(0, checkStr.length));
-
- assert.ok(childDidExit);
- assert.equal(childStr.substr(0, checkStr.length), checkStr);
- console.log('ok');
- });
-}
-
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var dns = require('dns');
-var fs = require('fs');
-var net = require('net');
-var tracing = require('tracing');
-
-var addListener = tracing.addAsyncListener;
-var removeListener = tracing.removeAsyncListener;
-var errorMsgs = [];
-var currentMsg = '';
-var caught = 0;
-var expectCaught = 0;
-var exitCbRan = false;
-
-var callbacksObj = {
- error: function(value, er) {
- var idx = errorMsgs.indexOf(er.message);
-
- caught++;
-
- if (-1 < idx)
- errorMsgs.splice(idx, 1);
-
- return currentMsg === er.message;
- }
-};
-
-var listener = tracing.createAsyncListener(callbacksObj);
-
-process.on('exit', function(code) {
- removeListener(listener);
-
- // Something else went wrong, no need to further check.
- if (code > 0)
- return;
-
- // Make sure the exit callback only runs once.
- assert.ok(!exitCbRan);
- exitCbRan = true;
-
- // Check if any error messages weren't removed from the msg queue.
- if (errorMsgs.length > 0)
- throw new Error('Errors not fired: ' + errorMsgs);
-
- assert.equal(caught, expectCaught, 'caught all expected errors');
- process._rawDebug('ok');
-});
-
-
-// Catch synchronous throws
-errorMsgs.push('sync throw');
-process.nextTick(function() {
- addListener(listener);
-
- expectCaught++;
- currentMsg = 'sync throw';
- throw new Error(currentMsg);
-
- removeListener(listener);
-});
-
-
-// Simple cases
-errorMsgs.push('setTimeout - simple');
-errorMsgs.push('setImmediate - simple');
-errorMsgs.push('setInterval - simple');
-errorMsgs.push('process.nextTick - simple');
-process.nextTick(function() {
- addListener(listener);
-
- setTimeout(function() {
- currentMsg = 'setTimeout - simple';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- setImmediate(function() {
- currentMsg = 'setImmediate - simple';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- var b = setInterval(function() {
- clearInterval(b);
- currentMsg = 'setInterval - simple';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- process.nextTick(function() {
- currentMsg = 'process.nextTick - simple';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- removeListener(listener);
-});
-
-
-// Deeply nested
-errorMsgs.push('setInterval - nested');
-errorMsgs.push('setImmediate - nested');
-errorMsgs.push('process.nextTick - nested');
-errorMsgs.push('setTimeout2 - nested');
-errorMsgs.push('setTimeout - nested');
-process.nextTick(function() {
- addListener(listener);
-
- setTimeout(function() {
- process.nextTick(function() {
- setImmediate(function() {
- var b = setInterval(function() {
- clearInterval(b);
- currentMsg = 'setInterval - nested';
- throw new Error(currentMsg);
- });
- expectCaught++;
- currentMsg = 'setImmediate - nested';
- throw new Error(currentMsg);
- });
- expectCaught++;
- currentMsg = 'process.nextTick - nested';
- throw new Error(currentMsg);
- });
- expectCaught++;
- setTimeout(function() {
- currentMsg = 'setTimeout2 - nested';
- throw new Error(currentMsg);
- });
- expectCaught++;
- currentMsg = 'setTimeout - nested';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- removeListener(listener);
-});
-
-
-// FS
-errorMsgs.push('fs - file does not exist');
-errorMsgs.push('fs - exists');
-errorMsgs.push('fs - realpath');
-process.nextTick(function() {
- addListener(listener);
-
- fs.stat('does not exist', function(err, stats) {
- currentMsg = 'fs - file does not exist';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- fs.exists('hi all', function(exists) {
- currentMsg = 'fs - exists';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- fs.realpath('/some/path', function(err, resolved) {
- currentMsg = 'fs - realpath';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- removeListener(listener);
-});
-
-
-// Nested FS
-errorMsgs.push('fs - nested file does not exist');
-process.nextTick(function() {
- addListener(listener);
-
- setTimeout(function() {
- setImmediate(function() {
- var b = setInterval(function() {
- clearInterval(b);
- process.nextTick(function() {
- fs.stat('does not exist', function(err, stats) {
- currentMsg = 'fs - nested file does not exist';
- throw new Error(currentMsg);
- });
- expectCaught++;
- });
- });
- });
- });
-
- removeListener(listener);
-});
-
-
-// Net
-errorMsgs.push('net - connection listener');
-errorMsgs.push('net - client connect');
-errorMsgs.push('net - server listening');
-process.nextTick(function() {
- addListener(listener);
-
- var server = net.createServer(function(c) {
- server.close();
- currentMsg = 'net - connection listener';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- server.listen(common.PORT, function() {
- var client = net.connect(common.PORT, function() {
- client.end();
- currentMsg = 'net - client connect';
- throw new Error(currentMsg);
- });
- expectCaught++;
- currentMsg = 'net - server listening';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- removeListener(listener);
-});
-
-
-// DNS
-errorMsgs.push('dns - lookup');
-process.nextTick(function() {
- addListener(listener);
-
- dns.lookup('localhost', function() {
- currentMsg = 'dns - lookup';
- throw new Error(currentMsg);
- });
- expectCaught++;
-
- removeListener(listener);
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var addListener = tracing.addAsyncListener;
-var removeListener = tracing.removeAsyncListener;
-var caught = [];
-var expect = [];
-
-var callbacksObj = {
- error: function(value, er) {
- process._rawDebug('caught', er.message);
- caught.push(er.message);
- return (expect.indexOf(er.message) !== -1);
- }
-};
-
-var listener = tracing.createAsyncListener(callbacksObj);
-
-process.on('exit', function(code) {
- removeListener(listener);
-
- if (code > 0)
- return;
-
- expect = expect.sort();
- caught = caught.sort();
-
- process._rawDebug('expect', expect);
- process._rawDebug('caught', caught);
- assert.deepEqual(caught, expect, 'caught all expected errors');
- process._rawDebug('ok');
-});
-
-
-expect.push('immediate simple a');
-expect.push('immediate simple b');
-process.nextTick(function() {
- addListener(listener);
- // Tests for a setImmediate specific bug encountered while implementing
- // AsyncListeners.
- setImmediate(function() {
- throw new Error('immediate simple a');
- });
- setImmediate(function() {
- throw new Error('immediate simple b');
- });
- removeListener(listener);
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-var val;
-var callbacks = {
- create: function() {
- return 42;
- },
- before: function() {
- tracing.removeAsyncListener(listener);
- tracing.addAsyncListener(listener);
- },
- after: function(context, storage) {
- val = storage;
- }
-};
-
-var listener = tracing.addAsyncListener(callbacks);
-
-process.nextTick(function() {});
-
-process.on('exit', function(status) {
- tracing.removeAsyncListener(listener);
- assert.equal(status, 0);
- assert.equal(val, 42);
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-var set = 0;
-
-var asyncNoHandleError = {
- before: function() {
- set++;
- },
- after: function() {
- set++;
- }
-}
-
-var key = tracing.addAsyncListener(asyncNoHandleError);
-
-tracing.removeAsyncListener(key);
-
-process.nextTick(function() { });
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // The async handler should never be called.
- assert.equal(set, 0);
- console.log('ok');
-});
-
-
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-var done = false;
-var callbacks = {
- before: function() {
- tracing.removeAsyncListener(listener);
- },
- after: function() {
- done = true;
- }
-};
-
-var listener = tracing.addAsyncListener(callbacks);
-
-process.nextTick(function() {});
-
-process.on('exit', function(status) {
- tracing.removeAsyncListener(listener);
- assert.equal(status, 0);
- assert.ok(done);
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var set = 0;
-var asyncNoHandleError = {
- error: function() {
- set++;
- }
-}
-
-var key = tracing.addAsyncListener(asyncNoHandleError);
-
-process.nextTick(function() {
- throw 1;
-});
-
-tracing.removeAsyncListener(key);
-
-var uncaughtFired = false;
-process.on('uncaughtException', function() {
- uncaughtFired = true;
-
- // Throwing should call the error handler once, then propagate to
- // uncaughtException
- assert.equal(set, 1);
-});
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- assert.ok(uncaughtFired);
- console.log('ok');
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var set = 0;
-var asyncNoHandleError = {
- before: function() {
- set++;
- },
- after: function() {
- set++;
- }
-}
-
-var key = tracing.addAsyncListener(asyncNoHandleError);
-
-process.nextTick(function() { });
-
-tracing.removeAsyncListener(key);
-
-process.on('exit', function(code) {
- // If the exit code isn't ok then return early to throw the stack that
- // caused the bad return code.
- if (code !== 0)
- return;
-
- // Calling removeAsyncListener *after* a callback is scheduled
- // should not affect the handler from responding to the callback.
- assert.equal(set, 2);
- console.log('ok');
-});
-
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var net = require('net');
-var tracing = require('tracing');
-
-var errMsg = 'net - error: server connection';
-var cntr = 0;
-var al = tracing.addAsyncListener({
- error: function(stor, er) {
- cntr++;
- process._rawDebug('Handling error: ' + er.message);
- assert.equal(errMsg, er.message);
- return true;
- }
-});
-
-process.on('exit', function(status) {
- tracing.removeAsyncListener(al);
-
- console.log('exit status:', status);
- assert.equal(status, 0);
- console.log('cntr:', cntr);
- assert.equal(cntr, 1);
- console.log('ok');
-});
-
-
-var server = net.createServer(function(c) {
- this.close();
- throw new Error(errMsg);
-});
-
-
-server.listen(common.PORT, function() {
- net.connect(common.PORT, function() {
- this.destroy();
- });
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-var cntr = 0;
-var al = tracing.createAsyncListener({
- create: function() { cntr++; },
-});
-
-process.on('exit', function() {
- assert.equal(cntr, 4);
- console.log('ok');
-});
-
-tracing.addAsyncListener(al);
-
-process.nextTick(function() {
- tracing.addAsyncListener(al);
- process.nextTick(function() {
- tracing.addAsyncListener(al);
- process.nextTick(function() {
- process.nextTick(function() { });
- });
- });
-});
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var tracing = require('tracing');
-
-// If there is an uncaughtException listener then the error thrown from
-// "before" will be considered handled, thus calling setImmediate to
-// finish execution of the nextTickQueue. This in turn will cause "before"
-// to fire again, entering into an infinite loop.
-// So the asyncQueue is cleared from the returned setImmediate in
-// _fatalException to prevent this from happening.
-var cntr = 0;
-
-
-tracing.addAsyncListener({
- before: function() {
- if (++cntr > 1) {
- // Can't throw since uncaughtException will also catch that.
- process._rawDebug('Error: Multiple before callbacks called');
- process.exit(1);
- }
- throw new Error('before');
- }
-});
-
-process.on('uncaughtException', function() { });
-
-process.nextTick();
+++ /dev/null
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common');
-var assert = require('assert');
-var net = require('net');
-var fs = require('fs');
-var dgram = require('dgram');
-var tracing = require('tracing');
-
-var addListener = tracing.addAsyncListener;
-var removeListener = tracing.removeAsyncListener;
-var actualAsync = 0;
-var expectAsync = 0;
-
-var callbacks = {
- create: function onAsync() {
- actualAsync++;
- }
-};
-
-var listener = tracing.createAsyncListener(callbacks);
-
-process.on('exit', function() {
- process._rawDebug('expected', expectAsync);
- process._rawDebug('actual ', actualAsync);
- // TODO(trevnorris): Not a great test. If one was missed, but others
- // overflowed then the test would still pass.
- assert.ok(actualAsync >= expectAsync);
-});
-
-
-// Test listeners side-by-side
-process.nextTick(function() {
- addListener(listener);
-
- var b = setInterval(function() {
- clearInterval(b);
- });
- expectAsync++;
-
- var c = setInterval(function() {
- clearInterval(c);
- });
- expectAsync++;
-
- setTimeout(function() { });
- expectAsync++;
-
- setTimeout(function() { });
- expectAsync++;
-
- process.nextTick(function() { });
- expectAsync++;
-
- process.nextTick(function() { });
- expectAsync++;
-
- setImmediate(function() { });
- expectAsync++;
-
- setImmediate(function() { });
- expectAsync++;
-
- setTimeout(function() { }, 10);
- expectAsync++;
-
- setTimeout(function() { }, 10);
- expectAsync++;
-
- removeListener(listener);
-});
-
-
-// Async listeners should propagate with nested callbacks
-process.nextTick(function() {
- addListener(listener);
- var interval = 3;
-
- process.nextTick(function() {
- setTimeout(function() {
- setImmediate(function() {
- var i = setInterval(function() {
- if (--interval <= 0)
- clearInterval(i);
- });
- expectAsync++;
- });
- expectAsync++;
- process.nextTick(function() {
- setImmediate(function() {
- setTimeout(function() { }, 20);
- expectAsync++;
- });
- expectAsync++;
- });
- expectAsync++;
- });
- expectAsync++;
- });
- expectAsync++;
-
- removeListener(listener);
-});
-
-
-// Test triggers with two async listeners
-process.nextTick(function() {
- addListener(listener);
- addListener(listener);
-
- setTimeout(function() {
- process.nextTick(function() { });
- expectAsync += 2;
- });
- expectAsync += 2;
-
- removeListener(listener);
- removeListener(listener);
-});
-
-
-// Test callbacks from fs I/O
-process.nextTick(function() {
- addListener(listener);
-
- fs.stat('something random', function(err, stat) { });
- expectAsync++;
-
- setImmediate(function() {
- fs.stat('random again', function(err, stat) { });
- expectAsync++;
- });
- expectAsync++;
-
- removeListener(listener);
-});
-
-
-// Test net I/O
-process.nextTick(function() {
- addListener(listener);
-
- var server = net.createServer(function(c) { });
- expectAsync++;
-
- server.listen(common.PORT, function() {
- server.close();
- expectAsync++;
- });
- expectAsync++;
-
- removeListener(listener);
-});
-
-
-// Test UDP
-process.nextTick(function() {
- addListener(listener);
-
- var server = dgram.createSocket('udp4');
- expectAsync++;
-
- server.bind(common.PORT);
-
- server.close();
- expectAsync++;
-
- removeListener(listener);
-});