| |
| |
| |
| |
| |
| |
| |
| 'use strict' |
|
|
| |
| |
| |
| |
|
|
| module.exports = onFinished |
| module.exports.isFinished = isFinished |
|
|
| |
| |
| |
| |
|
|
| var first = require('ee-first') |
|
|
| |
| |
| |
| |
|
|
| |
| var defer = typeof setImmediate === 'function' |
| ? setImmediate |
| : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| function onFinished(msg, listener) { |
| if (isFinished(msg) !== false) { |
| defer(listener, null, msg) |
| return msg |
| } |
|
|
| |
| attachListener(msg, listener) |
|
|
| return msg |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| function isFinished(msg) { |
| var socket = msg.socket |
|
|
| if (typeof msg.finished === 'boolean') { |
| |
| return Boolean(msg.finished || (socket && !socket.writable)) |
| } |
|
|
| if (typeof msg.complete === 'boolean') { |
| |
| return Boolean(msg.upgrade || !socket || !socket.readable || (msg.complete && !msg.readable)) |
| } |
|
|
| |
| return undefined |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| function attachFinishedListener(msg, callback) { |
| var eeMsg |
| var eeSocket |
| var finished = false |
|
|
| function onFinish(error) { |
| eeMsg.cancel() |
| eeSocket.cancel() |
|
|
| finished = true |
| callback(error) |
| } |
|
|
| |
| eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish) |
|
|
| function onSocket(socket) { |
| |
| msg.removeListener('socket', onSocket) |
|
|
| if (finished) return |
| if (eeMsg !== eeSocket) return |
|
|
| |
| eeSocket = first([[socket, 'error', 'close']], onFinish) |
| } |
|
|
| if (msg.socket) { |
| |
| onSocket(msg.socket) |
| return |
| } |
|
|
| |
| msg.on('socket', onSocket) |
|
|
| if (msg.socket === undefined) { |
| |
| patchAssignSocket(msg, onSocket) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| function attachListener(msg, listener) { |
| var attached = msg.__onFinished |
|
|
| |
| if (!attached || !attached.queue) { |
| attached = msg.__onFinished = createListener(msg) |
| attachFinishedListener(msg, attached) |
| } |
|
|
| attached.queue.push(listener) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| function createListener(msg) { |
| function listener(err) { |
| if (msg.__onFinished === listener) msg.__onFinished = null |
| if (!listener.queue) return |
|
|
| var queue = listener.queue |
| listener.queue = null |
|
|
| for (var i = 0; i < queue.length; i++) { |
| queue[i](err, msg) |
| } |
| } |
|
|
| listener.queue = [] |
|
|
| return listener |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| function patchAssignSocket(res, callback) { |
| var assignSocket = res.assignSocket |
|
|
| if (typeof assignSocket !== 'function') return |
|
|
| |
| res.assignSocket = function _assignSocket(socket) { |
| assignSocket.call(this, socket) |
| callback(socket) |
| } |
| } |
|
|