Skip to content
This repository was archived by the owner on Aug 29, 2023. It is now read-only.

Commit 3813100

Browse files
authored
fix: hanging close promise (#140)
1 parent 8661c09 commit 3813100

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/socket-to-conn.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ module.exports = (socket, options) => {
7878
resolve()
7979
}, CLOSE_TIMEOUT)
8080

81-
socket.once('close', () => clearTimeout(timeout))
81+
socket.once('close', () => {
82+
clearTimeout(timeout)
83+
resolve()
84+
})
8285
socket.end(err => {
8386
maConn.timeline.close = Date.now()
8487
if (err) return reject(err)

test/connection.spec.js

+32
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,36 @@ describe('valid localAddr and remoteAddr', () => {
5050
expect(dialerConn.remoteAddr.toString())
5151
.to.equal(listenerConn.localAddr.toString())
5252
})
53+
54+
it('should handle multiple simultaneous closes', async () => {
55+
// Create a Promise that resolves when a connection is handled
56+
let handled
57+
const handlerPromise = new Promise(resolve => { handled = resolve })
58+
59+
const handler = conn => handled(conn)
60+
61+
// Create a listener with the handler
62+
const listener = tcp.createListener(handler)
63+
64+
// Listen on the multi-address
65+
await listener.listen(ma)
66+
67+
const localAddrs = listener.getAddrs()
68+
expect(localAddrs.length).to.equal(1)
69+
70+
// Dial to that address
71+
const dialerConn = await tcp.dial(localAddrs[0])
72+
73+
// Wait for the incoming dial to be handled
74+
await handlerPromise
75+
76+
// Close the listener with two simultaneous calls to `close`
77+
await Promise.race([
78+
new Promise((resolve, reject) => setTimeout(() => reject(new Error('Timed out waiting for connection close')), 500)),
79+
await Promise.all([
80+
dialerConn.close(),
81+
dialerConn.close()
82+
])
83+
])
84+
})
5385
})

0 commit comments

Comments
 (0)