From: Trevor Norris Date: Tue, 9 Dec 2014 15:01:05 +0000 (+0100) Subject: src: remove Async Listener X-Git-Tag: v1.0.0-release~208 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0d60ab3efedd8b2fca607cc5ede7f866be412a0e;p=platform%2Fupstream%2Fnodejs.git src: remove Async Listener Async Listener was the name of the user-facing JS API, and is being completely removed. Instead low level hooks directly into the mechanism that AL used will be introduced in a future commit. PR-URL: https://github.com/joyent/node/pull/8110 Signed-off-by: Trevor Norris Reviewed-by: Fedor Indutny Reviewed-by: Alexis Campailla Reviewed-by: Julien Gilli --- diff --git a/doc/api/tracing.markdown b/doc/api/tracing.markdown index fc106ca58..8802e2991 100644 --- a/doc/api/tracing.markdown +++ b/doc/api/tracing.markdown @@ -5,16 +5,6 @@ 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 @@ -73,216 +63,4 @@ v8.setFlagsFromString('--trace_gc'); 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 + diff --git a/lib/timers.js b/lib/timers.js index b5fd04ee3..7fa683eac 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -32,21 +32,6 @@ var TIMEOUT_MAX = 2147483647; // 2^31-1 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 // @@ -61,11 +46,6 @@ delete tracing._unloadAsyncQueue; // 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) { @@ -102,7 +82,7 @@ function listOnTimeout() { 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) { @@ -124,19 +104,13 @@ function listOnTimeout() { 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) { @@ -206,11 +180,6 @@ exports.active = function(item) { 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); }; @@ -356,18 +325,15 @@ L.init(immediateQueue); 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(); @@ -391,8 +357,6 @@ function processImmediate() { if (domain) domain.exit(); - if (hasQueue) - unloadAsyncQueue(immediate); } // Only round-trip to C++ land if we have to. Calling clearImmediate() on an @@ -408,11 +372,8 @@ function Immediate() { } 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) { @@ -438,9 +399,6 @@ 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; @@ -474,7 +432,7 @@ function unrefTimeout() { debug('unrefTimer fired'); - var diff, domain, first, hasQueue, threw; + var diff, domain, first, threw; while (first = L.peek(unrefList)) { diff = now - first._idleStart; @@ -492,11 +450,8 @@ function unrefTimeout() { 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'); @@ -504,8 +459,6 @@ function unrefTimeout() { threw = false; if (domain) domain.exit(); - if (hasQueue) - unloadAsyncQueue(first); } finally { if (threw) process.nextTick(unrefTimeout); } diff --git a/lib/tracing.js b/lib/tracing.js index 52d7e27dd..f3cddb313 100644 --- a/lib/tracing.js +++ b/lib/tracing.js @@ -35,13 +35,6 @@ exports._nodeInitialization = function nodeInitialization(pobj) { 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; }; @@ -70,329 +63,3 @@ v8.on('removeListener', function(name) { } }); - -// 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; -} diff --git a/src/async-wrap-inl.h b/src/async-wrap-inl.h index 750466b3d..d64aeab2c 100644 --- a/src/async-wrap-inl.h +++ b/src/async-wrap-inl.h @@ -37,20 +37,7 @@ inline AsyncWrap::AsyncWrap(Environment* env, v8::Handle 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 val = object.As(); - env->async_listener_run_function()->Call(env->process_object(), 1, &val); - - if (!try_catch.HasCaught()) - async_flags_ |= HAS_ASYNC_LISTENER; } @@ -59,11 +46,6 @@ inline uint32_t AsyncWrap::provider_type() const { } -inline bool AsyncWrap::has_async_listener() { - return async_flags_ & HAS_ASYNC_LISTENER; -} - - // I hate you domains. inline v8::Handle AsyncWrap::MakeDomainCallback( const v8::Handle cb, @@ -79,14 +61,6 @@ inline v8::Handle AsyncWrap::MakeDomainCallback( v8::TryCatch try_catch; try_catch.SetVerbose(true); - if (has_async_listener()) { - v8::Local val = context.As(); - 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(); @@ -119,14 +93,6 @@ inline v8::Handle AsyncWrap::MakeDomainCallback( } } - if (has_async_listener()) { - v8::Local val = context.As(); - 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()) { @@ -172,28 +138,12 @@ inline v8::Handle AsyncWrap::MakeCallback( v8::TryCatch try_catch; try_catch.SetVerbose(true); - if (has_async_listener()) { - v8::Local val = context.As(); - env()->async_listener_load_function()->Call(process, 1, &val); - - if (try_catch.HasCaught()) - return v8::Undefined(env()->isolate()); - } - v8::Local ret = cb->Call(context, argc, argv); if (try_catch.HasCaught()) { return Undefined(env()->isolate()); } - if (has_async_listener()) { - v8::Local val = context.As(); - 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()) { diff --git a/src/async-wrap.h b/src/async-wrap.h index 08aff641b..bac927fc8 100644 --- a/src/async-wrap.h +++ b/src/async-wrap.h @@ -30,11 +30,6 @@ namespace node { class AsyncWrap : public BaseObject { public: - enum AsyncFlags { - NO_OPTIONS = 0, - HAS_ASYNC_LISTENER = 1 - }; - enum ProviderType { PROVIDER_NONE = 1 << 0, PROVIDER_CARES = 1 << 1, @@ -63,8 +58,6 @@ class AsyncWrap : public BaseObject { inline virtual ~AsyncWrap() override = default; - inline bool has_async_listener(); - inline uint32_t provider_type() const; // Only call these within a valid HandleScope. @@ -88,7 +81,6 @@ class AsyncWrap : public BaseObject { int argc, v8::Handle* argv); - uint32_t async_flags_; uint32_t provider_type_; }; diff --git a/src/env-inl.h b/src/env-inl.h index b770538e6..b40272cbd 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -111,27 +111,6 @@ inline v8::Isolate* Environment::IsolateData::isolate() const { 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; } @@ -277,16 +256,6 @@ inline v8::Isolate* Environment::isolate() const { return isolate_; } -inline bool Environment::has_async_listener() const { - // The const_cast is okay, it doesn't violate conceptual const-ness. - return const_cast(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(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() && @@ -338,10 +307,6 @@ inline uv_loop_t* Environment::event_loop() const { return isolate_data()->event_loop(); } -inline Environment::AsyncListener* Environment::async_listener() { - return &async_listener_count_; -} - inline Environment::DomainFlag* Environment::domain_flag() { return &domain_flag_; } diff --git a/src/env.h b/src/env.h index 5eac220ea..68ec7224d 100644 --- a/src/env.h +++ b/src/env.h @@ -64,7 +64,6 @@ namespace node { 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") \ @@ -250,9 +249,6 @@ namespace node { 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) \ @@ -286,28 +282,6 @@ RB_HEAD(ares_task_list, ares_task_t); 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(); @@ -399,7 +373,6 @@ class Environment { 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; @@ -419,7 +392,6 @@ class Environment { void *arg); inline void FinishHandleCleanup(uv_handle_t* handle); - inline AsyncListener* async_listener(); inline DomainFlag* domain_flag(); inline TickInfo* tick_info(); @@ -513,7 +485,6 @@ class Environment { 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_; diff --git a/src/node.cc b/src/node.cc index 6e3d7ff91..c07a0d9c0 100644 --- a/src/node.cc +++ b/src/node.cc @@ -918,31 +918,6 @@ Local WinapiErrnoException(Isolate* isolate, #endif -void SetupAsyncListener(const FunctionCallbackInfo& 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()); - env->set_async_listener_load_function(args[2].As()); - env->set_async_listener_unload_function(args[3].As()); - - Local async_listener_flag_obj = args[0].As(); - 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& args) { Environment* env = Environment::GetCurrent(args); @@ -1026,20 +1001,6 @@ Handle MakeDomainCallback(Environment* env, TryCatch try_catch; try_catch.SetVerbose(true); - bool has_async_queue = false; - - if (recv->IsObject()) { - object = recv.As(); - // 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()) { @@ -1077,13 +1038,6 @@ Handle MakeDomainCallback(Environment* env, } } - 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) { @@ -1135,28 +1089,12 @@ Handle MakeCallback(Environment* env, TryCatch try_catch; try_catch.SetVerbose(true); - // TODO(trevnorris): This is sucky for performance. Fix it. - bool has_async_queue = - recv->IsObject() && recv.As()->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 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()) { @@ -2865,7 +2803,6 @@ void SetupProcessObject(Environment* env, 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); diff --git a/src/node.js b/src/node.js index 1684d036a..bedc6e025 100644 --- a/src/node.js +++ b/src/node.js @@ -232,14 +232,8 @@ }; 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; @@ -262,10 +256,6 @@ // 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; @@ -299,12 +289,7 @@ }; 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. @@ -318,10 +303,6 @@ 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; @@ -368,7 +349,7 @@ // 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(); @@ -376,9 +357,6 @@ tock = nextTickQueue[tickInfo[kIndex]++]; callback = tock.callback; threw = true; - hasQueue = !!tock._asyncQueue; - if (hasQueue) - _loadAsyncQueue(tock); try { callback(); threw = false; @@ -386,8 +364,6 @@ if (threw) tickDone(); } - if (hasQueue) - _unloadAsyncQueue(tock); if (1e4 < tickInfo[kIndex]) tickDone(); } @@ -396,7 +372,7 @@ } function _tickDomainCallback() { - var callback, domain, hasQueue, threw, tock; + var callback, domain, threw, tock; scheduleMicrotasks(); @@ -404,9 +380,6 @@ tock = nextTickQueue[tickInfo[kIndex]++]; callback = tock.callback; domain = tock.domain; - hasQueue = !!tock._asyncQueue; - if (hasQueue) - _loadAsyncQueue(tock); if (domain) domain.enter(); threw = true; @@ -417,8 +390,6 @@ if (threw) tickDone(); } - if (hasQueue) - _unloadAsyncQueue(tock); if (1e4 < tickInfo[kIndex]) tickDone(); if (domain) @@ -435,13 +406,9 @@ 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]++; } diff --git a/test/simple/test-asynclistener-error-multiple-handled.js b/test/simple/test-asynclistener-error-multiple-handled.js deleted file mode 100644 index 576ce58e4..000000000 --- a/test/simple/test-asynclistener-error-multiple-handled.js +++ /dev/null @@ -1,76 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-error-multiple-mix.js b/test/simple/test-asynclistener-error-multiple-mix.js deleted file mode 100644 index 83716bc28..000000000 --- a/test/simple/test-asynclistener-error-multiple-mix.js +++ /dev/null @@ -1,65 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-error-multiple-unhandled.js b/test/simple/test-asynclistener-error-multiple-unhandled.js deleted file mode 100644 index 33afaaa81..000000000 --- a/test/simple/test-asynclistener-error-multiple-unhandled.js +++ /dev/null @@ -1,79 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-error-net.js b/test/simple/test-asynclistener-error-net.js deleted file mode 100644 index 26a337a50..000000000 --- a/test/simple/test-asynclistener-error-net.js +++ /dev/null @@ -1,108 +0,0 @@ -// 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++; -} diff --git a/test/simple/test-asynclistener-error-throw-in-after.js b/test/simple/test-asynclistener-error-throw-in-after.js deleted file mode 100644 index 3eb02e165..000000000 --- a/test/simple/test-asynclistener-error-throw-in-after.js +++ /dev/null @@ -1,62 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-error-throw-in-before-multiple.js b/test/simple/test-asynclistener-error-throw-in-before-multiple.js deleted file mode 100644 index b9aecf397..000000000 --- a/test/simple/test-asynclistener-error-throw-in-before-multiple.js +++ /dev/null @@ -1,80 +0,0 @@ -// 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'); -}); - diff --git a/test/simple/test-asynclistener-error-throw-in-before.js b/test/simple/test-asynclistener-error-throw-in-before.js deleted file mode 100644 index fb6b6eeec..000000000 --- a/test/simple/test-asynclistener-error-throw-in-before.js +++ /dev/null @@ -1,64 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-error-throw-in-error.js b/test/simple/test-asynclistener-error-throw-in-error.js deleted file mode 100644 index c66d688fb..000000000 --- a/test/simple/test-asynclistener-error-throw-in-error.js +++ /dev/null @@ -1,87 +0,0 @@ -// 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'); - }); -} - diff --git a/test/simple/test-asynclistener-error.js b/test/simple/test-asynclistener-error.js deleted file mode 100644 index 6e5f31b03..000000000 --- a/test/simple/test-asynclistener-error.js +++ /dev/null @@ -1,257 +0,0 @@ -// 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); -}); diff --git a/test/simple/test-asynclistener-multi-timeout.js b/test/simple/test-asynclistener-multi-timeout.js deleted file mode 100644 index 9af482054..000000000 --- a/test/simple/test-asynclistener-multi-timeout.js +++ /dev/null @@ -1,70 +0,0 @@ -// 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); -}); diff --git a/test/simple/test-asynclistener-remove-add-in-before.js b/test/simple/test-asynclistener-remove-add-in-before.js deleted file mode 100644 index af0bc78e0..000000000 --- a/test/simple/test-asynclistener-remove-add-in-before.js +++ /dev/null @@ -1,47 +0,0 @@ -// 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); -}); diff --git a/test/simple/test-asynclistener-remove-before.js b/test/simple/test-asynclistener-remove-before.js deleted file mode 100644 index bc306dbc3..000000000 --- a/test/simple/test-asynclistener-remove-before.js +++ /dev/null @@ -1,53 +0,0 @@ -// 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'); -}); - - diff --git a/test/simple/test-asynclistener-remove-in-before.js b/test/simple/test-asynclistener-remove-in-before.js deleted file mode 100644 index 06f470ce0..000000000 --- a/test/simple/test-asynclistener-remove-in-before.js +++ /dev/null @@ -1,43 +0,0 @@ -// 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); -}); diff --git a/test/simple/test-asynclistener-remove-inflight-error.js b/test/simple/test-asynclistener-remove-inflight-error.js deleted file mode 100644 index 1b9150152..000000000 --- a/test/simple/test-asynclistener-remove-inflight-error.js +++ /dev/null @@ -1,58 +0,0 @@ -// 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'); -}); diff --git a/test/simple/test-asynclistener-remove-inflight.js b/test/simple/test-asynclistener-remove-inflight.js deleted file mode 100644 index a21b1923f..000000000 --- a/test/simple/test-asynclistener-remove-inflight.js +++ /dev/null @@ -1,53 +0,0 @@ -// 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'); -}); - diff --git a/test/simple/test-asynclistener-run-error-once.js b/test/simple/test-asynclistener-run-error-once.js deleted file mode 100644 index 154decb99..000000000 --- a/test/simple/test-asynclistener-run-error-once.js +++ /dev/null @@ -1,59 +0,0 @@ -// 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(); - }); -}); diff --git a/test/simple/test-asynclistener-run-inst-once.js b/test/simple/test-asynclistener-run-inst-once.js deleted file mode 100644 index b1492528e..000000000 --- a/test/simple/test-asynclistener-run-inst-once.js +++ /dev/null @@ -1,46 +0,0 @@ -// 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() { }); - }); - }); -}); diff --git a/test/simple/test-asynclistener-throw-before-infinite-recursion.js b/test/simple/test-asynclistener-throw-before-infinite-recursion.js deleted file mode 100644 index fdbb50be1..000000000 --- a/test/simple/test-asynclistener-throw-before-infinite-recursion.js +++ /dev/null @@ -1,48 +0,0 @@ -// 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(); diff --git a/test/simple/test-asynclistener.js b/test/simple/test-asynclistener.js deleted file mode 100644 index 4c29ec905..000000000 --- a/test/simple/test-asynclistener.js +++ /dev/null @@ -1,188 +0,0 @@ -// 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); -});