events,lib: don't require EE#listenerCount()
authorJeremiah Senkpiel <fishrock123@rocketmail.com>
Wed, 2 Sep 2015 16:23:49 +0000 (12:23 -0400)
committerRod Vagg <rod@vagg.org>
Sun, 6 Sep 2015 11:39:00 +0000 (21:39 +1000)
Now parts of our public and public-ish APIs fall back to old-style
listenerCount() if the emitter does not have a listenerCount function.

Fixes: https://github.com/nodejs/node/issues/2655
Refs: 8f58fb92fff904a6ca58fd0df9ee5a1816e5b84e

PR-URL: https://github.com/nodejs/node/pull/2661
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
lib/_http_server.js
lib/_stream_readable.js
lib/events.js
lib/stream.js
test/parallel/test-stream-pipe-without-listenerCount.js [new file with mode: 0644]

index dd787fa..16460fc 100644 (file)
@@ -374,7 +374,7 @@ function connectionListener(socket) {
       parser = null;
 
       var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
-      if (self.listenerCount(eventName) > 0) {
+      if (EventEmitter.listenerCount(self, eventName) > 0) {
         debug('SERVER have listener for %s', eventName);
         var bodyHead = d.slice(bytesParsed, d.length);
 
@@ -497,7 +497,7 @@ function connectionListener(socket) {
         (req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
         continueExpression.test(req.headers['expect'])) {
       res._expect_continue = true;
-      if (self.listenerCount('checkContinue') > 0) {
+      if (EventEmitter.listenerCount(self, 'checkContinue') > 0) {
         self.emit('checkContinue', req, res);
       } else {
         res.writeContinue();
index 681c3ea..c6bd0c1 100644 (file)
@@ -537,7 +537,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
     debug('onerror', er);
     unpipe();
     dest.removeListener('error', onerror);
-    if (dest.listenerCount('error') === 0)
+    if (EE.listenerCount(dest, 'error') === 0)
       dest.emit('error', er);
   }
   // This is a brutally ugly hack to make sure that our error handler
@@ -586,7 +586,7 @@ function pipeOnDrain(src) {
     debug('pipeOnDrain', state.awaitDrain);
     if (state.awaitDrain)
       state.awaitDrain--;
-    if (state.awaitDrain === 0 && src.listenerCount('data')) {
+    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
       state.flowing = true;
       flow(src);
     }
index 722b645..ea3f283 100644 (file)
@@ -395,10 +395,15 @@ EventEmitter.prototype.listeners = function listeners(type) {
 };
 
 EventEmitter.listenerCount = function(emitter, type) {
-  return emitter.listenerCount(type);
+  if (typeof emitter.listenerCount === 'function') {
+    return emitter.listenerCount(type);
+  } else {
+    return listenerCount.call(emitter, type);
+  }
 };
 
-EventEmitter.prototype.listenerCount = function listenerCount(type) {
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
   const events = this._events;
 
   if (events) {
index 2e0cdfc..8d3535d 100644 (file)
@@ -70,7 +70,7 @@ Stream.prototype.pipe = function(dest, options) {
   // don't leave dangling pipes when there are errors.
   function onerror(er) {
     cleanup();
-    if (this.listenerCount('error') === 0) {
+    if (EE.listenerCount(this, 'error') === 0) {
       throw er; // Unhandled stream error in pipe.
     }
   }
diff --git a/test/parallel/test-stream-pipe-without-listenerCount.js b/test/parallel/test-stream-pipe-without-listenerCount.js
new file mode 100644 (file)
index 0000000..d7a6a6b
--- /dev/null
@@ -0,0 +1,19 @@
+'use strict';
+const common = require('../common');
+const stream = require('stream');
+
+const r = new stream.Stream();
+r.listenerCount = undefined;
+
+const w = new stream.Stream();
+w.listenerCount = undefined;
+
+w.on('pipe', function() {
+  r.emit('error', new Error('Readable Error'));
+  w.emit('error', new Error('Writable Error'));
+});
+r.on('error', common.mustCall(noop));
+w.on('error', common.mustCall(noop));
+r.pipe(w);
+
+function noop() {};