summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/dgram.js32
-rw-r--r--test/parallel/test-dgram-close-in-listening.js18
2 files changed, 39 insertions, 11 deletions
diff --git a/lib/dgram.js b/lib/dgram.js
index e6cc169dc6..c088bffa7f 100644
--- a/lib/dgram.js
+++ b/lib/dgram.js
@@ -283,20 +283,25 @@ function fixBufferList(list) {
function enqueue(self, toEnqueue) {
// If the send queue hasn't been initialized yet, do it, and install an
// event handler that flushes the send queue after binding is done.
- if (!self._sendQueue) {
- self._sendQueue = [];
- self.once('listening', function() {
- // Flush the send queue.
- for (var i = 0; i < this._sendQueue.length; i++)
- this.send.apply(self, this._sendQueue[i]);
- this._sendQueue = undefined;
- });
+ if (!self._queue) {
+ self._queue = [];
+ self.once('listening', clearQueue);
}
- self._sendQueue.push(toEnqueue);
+ self._queue.push(toEnqueue);
return;
}
+function clearQueue() {
+ const queue = this._queue;
+ this._queue = undefined;
+
+ // Flush the send queue.
+ for (var i = 0; i < queue.length; i++)
+ queue[i]();
+}
+
+
// valid combinations
// send(buffer, offset, length, port, address, callback)
// send(buffer, offset, length, port, address)
@@ -353,7 +358,7 @@ Socket.prototype.send = function(buffer,
// If the socket hasn't been bound yet, push the outbound packet onto the
// send queue and send after binding is complete.
if (self._bindState != BIND_STATE_BOUND) {
- enqueue(self, [list, port, address, callback]);
+ enqueue(self, self.send.bind(self, list, port, address, callback));
return;
}
@@ -407,10 +412,15 @@ function afterSend(err, sent) {
this.callback(err, sent);
}
-
Socket.prototype.close = function(callback) {
if (typeof callback === 'function')
this.on('close', callback);
+
+ if (this._queue) {
+ this._queue.push(this.close.bind(this));
+ return this;
+ }
+
this._healthCheck();
this._stopReceiving();
this._handle.close();
diff --git a/test/parallel/test-dgram-close-in-listening.js b/test/parallel/test-dgram-close-in-listening.js
new file mode 100644
index 0000000000..e181f40de6
--- /dev/null
+++ b/test/parallel/test-dgram-close-in-listening.js
@@ -0,0 +1,18 @@
+'use strict';
+// Ensure that if a dgram socket is closed before the sendQueue is drained
+// will not crash
+
+const common = require('../common');
+const dgram = require('dgram');
+
+const buf = Buffer.alloc(1024, 42);
+
+const socket = dgram.createSocket('udp4');
+
+socket.on('listening', function() {
+ socket.close();
+});
+
+// adds a listener to 'listening' to send the data when
+// the socket is available
+socket.send(buf, 0, buf.length, common.PORT, 'localhost');