summaryrefslogtreecommitdiff
path: root/lib/stream.js
diff options
context:
space:
mode:
authorFelix Geisendörfer <felix@debuggable.com>2011-04-14 20:33:54 +0200
committerRyan Dahl <ry@tinyclouds.org>2011-04-14 14:12:01 -0700
commit6c5b31bd80d2d38600d84a5be0ae9c5bbad94c01 (patch)
tree9e2a6d70414412470cdbfd4ffd3a198e40425f14 /lib/stream.js
parent8417870f513e6f1ab98e07fe95d3430dbec48b87 (diff)
downloadandroid-node-v8-6c5b31bd80d2d38600d84a5be0ae9c5bbad94c01.tar.gz
android-node-v8-6c5b31bd80d2d38600d84a5be0ae9c5bbad94c01.tar.bz2
android-node-v8-6c5b31bd80d2d38600d84a5be0ae9c5bbad94c01.zip
Fix: Multiple pipes to the same stream were broken
When creating multiple .pipe()s to the same destination stream, the first source to end would close the destination, breaking all remaining pipes. This patch fixes the problem by keeping track of all open pipes, so that we only call end on destinations that have no more sources piping to them. closes #929
Diffstat (limited to 'lib/stream.js')
-rw-r--r--lib/stream.js29
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/stream.js b/lib/stream.js
index d31a9fe239..632c87d2e2 100644
--- a/lib/stream.js
+++ b/lib/stream.js
@@ -28,9 +28,13 @@ function Stream() {
util.inherits(Stream, events.EventEmitter);
exports.Stream = Stream;
+var pipes = [];
+
Stream.prototype.pipe = function(dest, options) {
var source = this;
+ pipes.push(dest);
+
function ondata(chunk) {
if (dest.writable) {
if (false === dest.write(chunk)) source.pause();
@@ -52,10 +56,18 @@ Stream.prototype.pipe = function(dest, options) {
if (!options || options.end !== false) {
function onend() {
+ var index = pipes.indexOf(dest);
+ pipes.splice(index, 1);
+
+ if (pipes.indexOf(dest) > -1) {
+ return;
+ }
+
dest.end();
}
source.on('end', onend);
+ source.on('close', onend);
}
/*
@@ -73,34 +85,35 @@ Stream.prototype.pipe = function(dest, options) {
source.emit('resume');
};
}
-
+
var onpause = function() {
source.pause();
}
dest.on('pause', onpause);
-
+
var onresume = function() {
if (source.readable) source.resume();
};
-
+
dest.on('resume', onresume);
-
+
var cleanup = function () {
source.removeListener('data', ondata);
dest.removeListener('drain', ondrain);
source.removeListener('end', onend);
-
+ source.removeListener('close', onend);
+
dest.removeListener('pause', onpause);
dest.removeListener('resume', onresume);
-
+
source.removeListener('end', cleanup);
source.removeListener('close', cleanup);
-
+
dest.removeListener('end', cleanup);
dest.removeListener('close', cleanup);
}
-
+
source.on('end', cleanup);
source.on('close', cleanup);